wrap up support for all built in C++ Arithmetic types
This commit is contained in:
parent
1a225dca67
commit
4b90fbd07a
@ -21,130 +21,30 @@ namespace chaiscript
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/// \brief Assigns a POD value from a Boxed_Numeric. Helps support operators between
|
||||
/// disparate POD types.
|
||||
/// \param[in,out] p1 object to assign to
|
||||
/// \param[in] v Boxed_Numeric to assign from
|
||||
/// \returns Reference to p1, to support normal C assignment semantics
|
||||
template<typename P1>
|
||||
P1 &assign_pod(P1 &p1, const Boxed_Numeric &v)
|
||||
{
|
||||
if (v.isfloat)
|
||||
{
|
||||
return (p1 = P1(v.d));
|
||||
} else {
|
||||
return (p1 = P1(v.i));
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Constructs a new POD value object from a Boxed_Numeric
|
||||
/// \param[in] v Boxed_Numeric to copy into the new object
|
||||
/// \returns The newly created object.
|
||||
template<typename P1>
|
||||
P1 construct_pod(Boxed_Numeric v)
|
||||
boost::shared_ptr<P1> construct_pod(Boxed_Numeric v)
|
||||
{
|
||||
if (v.isfloat)
|
||||
{
|
||||
return P1(v.d);
|
||||
} else {
|
||||
return P1(v.i);
|
||||
}
|
||||
boost::shared_ptr<P1> p(new P1());
|
||||
Boxed_Value bv(p);
|
||||
Boxed_Numeric nb(bv);
|
||||
nb = v;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Performs a bitwise and assignment (&=) on the given object with the given Boxed_Numeric
|
||||
/// \param[in,out] p1 object to bitwise and assign to
|
||||
/// \param[in] r Boxed_Numeric to assign from
|
||||
/// \returns Reference to p1, to support normal C assignment semantics
|
||||
template<typename P1>
|
||||
P1 &assign_bitwise_and_pod(P1 &p1, Boxed_Numeric r)
|
||||
{
|
||||
if (!r.isfloat)
|
||||
{
|
||||
return p1 &= P1(r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("&= only valid for integer types");
|
||||
}
|
||||
|
||||
/// \brief Performs a xor assignment (^=) on the given object with the given Boxed_Numeric
|
||||
/// \param[in,out] p1 object to xor assign to
|
||||
/// \param[in] r Boxed_Numeric to assign from
|
||||
/// \returns Reference to p1, to support normal C assignment semantics
|
||||
template<typename P1>
|
||||
P1 &assign_xor_pod(P1 &p1, Boxed_Numeric r)
|
||||
{
|
||||
if (!r.isfloat)
|
||||
{
|
||||
return p1 ^= P1(r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("^= only valid for integer types");
|
||||
}
|
||||
|
||||
/// \brief Performs a bitwise or assignment (|=) on the given object with the given Boxed_Numeric
|
||||
/// \param[in,out] p1 object to bitwise or assign to
|
||||
/// \param[in] r Boxed_Numeric to assign from
|
||||
/// \returns Reference to p1, to support normal C assignment semantics
|
||||
template<typename P1>
|
||||
P1 &assign_bitwise_or_pod(P1 &p1, Boxed_Numeric r)
|
||||
{
|
||||
if (!r.isfloat)
|
||||
{
|
||||
return p1 |= P1(r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("&= only valid for integer types");
|
||||
}
|
||||
|
||||
/// \brief Performs an assign shift left (<<=) on the given object with the given Boxed_Numeric
|
||||
/// \param[in,out] p1 object to assign shift left to
|
||||
/// \param[in] r Boxed_Numeric to assign from
|
||||
/// \returns Reference to p1, to support normal C assignment semantics
|
||||
template<typename P1>
|
||||
P1 &assign_left_shift_pod(P1 &p1, Boxed_Numeric r)
|
||||
{
|
||||
if (!r.isfloat)
|
||||
{
|
||||
return p1 <<= P1(r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("<<= only valid for integer types");
|
||||
}
|
||||
|
||||
|
||||
/// \brief Performs an assign remainder (%=) on the given object with the given Boxed_Numeric
|
||||
/// \param[in,out] p1 object to assign remainder to
|
||||
/// \param[in] r Boxed_Numeric to assign from
|
||||
/// \returns Reference to p1, to support normal C assignment semantics
|
||||
template<typename P1>
|
||||
P1 &assign_remainder_pod(P1 &p1, Boxed_Numeric r)
|
||||
{
|
||||
if (!r.isfloat)
|
||||
{
|
||||
return p1 %= P1(r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("%= only valid for integer types");
|
||||
}
|
||||
|
||||
|
||||
/// \brief Performs an assign shift right (>>=) on the given object with the given Boxed_Numeric
|
||||
/// \param[in,out] p1 object to assign shift right to
|
||||
/// \param[in] r Boxed_Numeric to assign from
|
||||
/// \returns Reference to p1, to support normal C assignment semantics
|
||||
template<typename P1>
|
||||
P1 &assign_right_shift_pod(P1 &p1, Boxed_Numeric r)
|
||||
{
|
||||
if (!r.isfloat)
|
||||
{
|
||||
return p1 >>= P1(r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast(">>= only valid for integer types");
|
||||
}
|
||||
|
||||
|
||||
/// \brief Adds a copy constructor for the given type to the given Model
|
||||
/// \param[in] type The name of the type. The copy constructor will be named "type".
|
||||
/// \param[in,out] m The Module to add the copy constructor to
|
||||
/// \tparam T The type to add a copy constructor for
|
||||
/// \returns The passed in ModulePtr, or the newly constructed one if the default param is used
|
||||
template<typename T>
|
||||
ModulePtr copy_constructor(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(constructor<T (const T &)>(), type);
|
||||
return m;
|
||||
}
|
||||
|
||||
/// \brief Add all comparison operators for the templated type. Used during bootstrap, also available to users.
|
||||
@ -164,76 +64,6 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
|
||||
/// \brief Add all arithmetic operators appropriate for integers for the templated type.
|
||||
/// Used during bootstrap, also available to users.
|
||||
/// \tparam T Type to create arithmetic operators for
|
||||
/// \param[in,out] m module to add arithmetic operators to
|
||||
/// \returns the passed in ModulePtr or the newly constructed one if the default params are used.
|
||||
template<typename T>
|
||||
ModulePtr opers_integer_arithmetic(ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
operators::assign_bitwise_and<T>(m);
|
||||
operators::assign_xor<T>(m);
|
||||
operators::assign_bitwise_or<T>(m);
|
||||
// operators::assign_difference<T>(m);
|
||||
operators::assign_left_shift<T>(m);
|
||||
// operators::assign_product<T>(m);
|
||||
// operators::assign_quotient<T>(m);
|
||||
// operators::assign_remainder<T>(m);
|
||||
operators::assign_right_shift<T>(m);
|
||||
// operators::assign_sum<T>(m);
|
||||
|
||||
// operators::prefix_decrement<T>(m);
|
||||
// operators::prefix_increment<T>(m);
|
||||
// operators::addition<T>(m);
|
||||
operators::unary_plus<T>(m);
|
||||
// operators::subtraction<T>(m);
|
||||
operators::unary_minus<T>(m);
|
||||
operators::bitwise_and<T>(m);
|
||||
operators::bitwise_compliment<T>(m);
|
||||
operators::bitwise_xor<T>(m);
|
||||
operators::bitwise_or<T>(m);
|
||||
// operators::division<T>(m);
|
||||
operators::left_shift<T>(m);
|
||||
// operators::multiplication<T>(m);
|
||||
operators::remainder<T>(m);
|
||||
operators::right_shift<T>(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
/// \brief Add all arithmetic operators appropriate for floating point numbers for the templated type.
|
||||
/// Used during bootstrap, also available to users.
|
||||
/// \tparam T Type to create arithmetic operators for
|
||||
/// \param[in,out] m module to add arithmetic operators to
|
||||
/// \returns the passed in ModulePtr or the newly constructed one if the default params are used.
|
||||
template<typename T>
|
||||
ModulePtr opers_float_arithmetic(ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
// operators::assign_difference<T>(m);
|
||||
// operators::assign_product<T>(m);
|
||||
// operators::assign_quotient<T>(m);
|
||||
// operators::assign_sum<T>(m);
|
||||
|
||||
// operators::addition<T>(m);
|
||||
operators::unary_plus<T>(m);
|
||||
// operators::subtraction<T>(m);
|
||||
operators::unary_minus<T>(m);
|
||||
// operators::division<T>(m);
|
||||
// operators::multiplication<T>(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
/// \brief Adds a copy constructor for the given type to the given Model
|
||||
/// \param[in] type The name of the type. The copy constructor will be named "type".
|
||||
/// \param[in,out] m The Module to add the copy constructor to
|
||||
/// \tparam T The type to add a copy constructor for
|
||||
/// \returns The passed in ModulePtr, or the newly constructed one if the default param is used
|
||||
template<typename T>
|
||||
ModulePtr copy_constructor(const std::string &type, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(constructor<T (const T &)>(), type);
|
||||
return m;
|
||||
}
|
||||
|
||||
/// \brief Adds default and copy constructors for the given type
|
||||
/// \param[in] type The name of the type to add the constructors for.
|
||||
@ -283,15 +113,6 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add assignment operator for T = POD.
|
||||
*/
|
||||
template<typename T>
|
||||
ModulePtr oper_assign_pod(ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(fun(&detail::assign_pod<T>), "=");
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all common functions for a POD type. All operators, and
|
||||
@ -301,52 +122,14 @@ namespace chaiscript
|
||||
ModulePtr bootstrap_pod_type(const std::string &name, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(user_type<T>(), name);
|
||||
basic_constructors<T>(name, m);
|
||||
operators::assign<T>(m);
|
||||
oper_assign_pod<T>(m);
|
||||
m->add(constructor<T ()>(), name);
|
||||
construct_pod<T>(name, m);
|
||||
|
||||
// m->add(fun(&detail::assign_sum_pod<T>), "+=");
|
||||
// m->add(fun(&detail::assign_difference_pod<T>), "-=");
|
||||
// m->add(fun(&detail::assign_product_pod<T>), "*=");
|
||||
// m->add(fun(&detail::assign_quotient_pod<T>), "/=");
|
||||
|
||||
m->add(fun(&to_string<T>), "to_string");
|
||||
m->add(fun(&parse_string<T>), "to_" + name);
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all common functions for a POD type. All operators, and
|
||||
* common conversions
|
||||
*/
|
||||
template<typename T>
|
||||
ModulePtr bootstrap_integer_type(const std::string &name, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
bootstrap_pod_type<T>(name, m);
|
||||
|
||||
m->add(fun(&detail::assign_bitwise_and_pod<T>), "&=");
|
||||
m->add(fun(&detail::assign_xor_pod<T>), "^=");
|
||||
m->add(fun(&detail::assign_bitwise_or_pod<T>), "|=");
|
||||
m->add(fun(&detail::assign_left_shift_pod<T>), "<<=");
|
||||
m->add(fun(&detail::assign_remainder_pod<T>), "%=");
|
||||
m->add(fun(&detail::assign_right_shift_pod<T>), ">>=");
|
||||
|
||||
opers_integer_arithmetic<T>(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all common functions for a POD type. All operators, and
|
||||
* common conversions
|
||||
*/
|
||||
template<typename T>
|
||||
ModulePtr bootstrap_float_type(const std::string &name, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
bootstrap_pod_type<T>(name, m);
|
||||
opers_float_arithmetic<T>(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* "clone" function for a shared_ptr type. This is used in the case
|
||||
@ -421,28 +204,48 @@ namespace chaiscript
|
||||
std::cout << s << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add all arithmetic operators for PODs
|
||||
*/
|
||||
static void opers_arithmetic_pod(ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(fun(&operators::addition<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "+");
|
||||
m->add(fun(&operators::subtraction<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "-");
|
||||
m->add(fun(&operators::bitwise_and<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "&");
|
||||
m->add(fun(&operators::bitwise_xor<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "^");
|
||||
m->add(fun(&operators::bitwise_or<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "|");
|
||||
m->add(fun(&operators::division<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "/");
|
||||
m->add(fun(&operators::left_shift<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "<<");
|
||||
m->add(fun(&operators::multiplication<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "*");
|
||||
m->add(fun(&operators::remainder<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), "%");
|
||||
m->add(fun(&operators::right_shift<Boxed_Value, Boxed_Numeric, Boxed_Numeric>), ">>");
|
||||
m->add(fun(&Boxed_Numeric::operator&=), "&=");
|
||||
m->add(fun(&Boxed_Numeric::operator|=), "|=");
|
||||
m->add(fun(&Boxed_Numeric::operator%=), "%=");
|
||||
m->add(fun(&Boxed_Numeric::operator^=), "^=");
|
||||
m->add(fun(&Boxed_Numeric::operator<<=), "<<=");
|
||||
m->add(fun(&Boxed_Numeric::operator>>=), ">>=");
|
||||
|
||||
m->add(fun(&Boxed_Numeric::operator&), "&");
|
||||
m->add(fun(&Boxed_Numeric::operator~), "~");
|
||||
m->add(fun(&Boxed_Numeric::operator^), "^");
|
||||
m->add(fun(&Boxed_Numeric::operator|), "|");
|
||||
m->add(fun(&Boxed_Numeric::operator<<), "<<");
|
||||
m->add(fun(&Boxed_Numeric::operator%), "%");
|
||||
m->add(fun(&Boxed_Numeric::operator>>), ">>");
|
||||
|
||||
m->add(fun<Boxed_Value (Boxed_Numeric::*)(const Boxed_Numeric &) const>(&Boxed_Numeric::operator=), "=");
|
||||
m->add(fun(&Boxed_Numeric::operator*=), "*=");
|
||||
m->add(fun(&Boxed_Numeric::operator/=), "/=");
|
||||
m->add(fun(&Boxed_Numeric::operator+=), "+=");
|
||||
m->add(fun(&Boxed_Numeric::operator-=), "-=");
|
||||
m->add(fun(&Boxed_Numeric::operator--), "--");
|
||||
m->add(fun(&Boxed_Numeric::operator++), "++");
|
||||
}
|
||||
m->add(fun(&Boxed_Numeric::operator/), "/");
|
||||
m->add(fun(&Boxed_Numeric::operator*), "*");
|
||||
m->add(fun<Boxed_Value (Boxed_Numeric::*)() const>(&Boxed_Numeric::operator+), "+");
|
||||
m->add(fun<Boxed_Value (Boxed_Numeric::*)() const>(&Boxed_Numeric::operator-), "-");
|
||||
m->add(fun<Boxed_Value (Boxed_Numeric::*)(const Boxed_Numeric &) const>(&Boxed_Numeric::operator+), "+");
|
||||
m->add(fun<Boxed_Value (Boxed_Numeric::*)(const Boxed_Numeric &) const>(&Boxed_Numeric::operator-), "-");
|
||||
|
||||
m->add(fun(&Boxed_Numeric::operator==), "==");
|
||||
m->add(fun(&Boxed_Numeric::operator>), ">");
|
||||
m->add(fun(&Boxed_Numeric::operator>=), ">=");
|
||||
m->add(fun(&Boxed_Numeric::operator<), "<");
|
||||
m->add(fun(&Boxed_Numeric::operator<=), "<=");
|
||||
m->add(fun(&Boxed_Numeric::operator!=), "!=");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a bound function object. The first param is the function to bind
|
||||
@ -633,15 +436,25 @@ namespace chaiscript
|
||||
m->add(fun(&throw_exception), "throw");
|
||||
m->add(fun(&what), "what");
|
||||
|
||||
bootstrap_float_type<double>("double", m);
|
||||
bootstrap_integer_type<int>("int", m);
|
||||
bootstrap_integer_type<size_t>("size_t", m);
|
||||
bootstrap_integer_type<char>("char", m);
|
||||
bootstrap_integer_type<boost::int64_t>("int64_t", m);
|
||||
bootstrap_pod_type<double>("double", m);
|
||||
bootstrap_pod_type<long double>("long_double", m);
|
||||
bootstrap_pod_type<float>("float", m);
|
||||
bootstrap_pod_type<int>("int", m);
|
||||
bootstrap_pod_type<unsigned int>("unsigned_int", m);
|
||||
bootstrap_pod_type<unsigned long>("unsigned_long", m);
|
||||
bootstrap_pod_type<size_t>("size_t", m);
|
||||
bootstrap_pod_type<char>("char", m);
|
||||
bootstrap_pod_type<boost::int8_t>("int8_t", m);
|
||||
bootstrap_pod_type<boost::int16_t>("int16_t", m);
|
||||
bootstrap_pod_type<boost::int32_t>("int32_t", m);
|
||||
bootstrap_pod_type<boost::int64_t>("int64_t", m);
|
||||
bootstrap_pod_type<boost::uint8_t>("uint8_t", m);
|
||||
bootstrap_pod_type<boost::uint16_t>("uint16_t", m);
|
||||
bootstrap_pod_type<boost::uint32_t>("uint32_t", m);
|
||||
bootstrap_pod_type<boost::uint64_t>("uint64_t", m);
|
||||
|
||||
operators::logical_compliment<bool>(m);
|
||||
|
||||
opers_comparison<Boxed_Numeric>(m);
|
||||
opers_arithmetic_pod(m);
|
||||
|
||||
|
||||
|
@ -42,10 +42,51 @@ namespace chaiscript
|
||||
struct equals
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
template<typename T, typename U>
|
||||
static bool go(const T &t, const U &u) { return t == u; }
|
||||
};
|
||||
|
||||
struct less_than
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
template<typename T, typename U>
|
||||
static bool go(const T &t, const U &u) { return t < u; }
|
||||
};
|
||||
|
||||
struct greater_than
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
template<typename T, typename U>
|
||||
static bool go(const T &t, const U &u) { return t > u; }
|
||||
};
|
||||
|
||||
struct greater_than_equal
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
template<typename T, typename U>
|
||||
static bool go(const T &t, const U &u) { return t >= u; }
|
||||
};
|
||||
|
||||
struct less_than_equal
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
template<typename T, typename U>
|
||||
static bool go(const T &t, const U &u) { return t <= u; }
|
||||
};
|
||||
|
||||
struct not_equal
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
template<typename T, typename U>
|
||||
static bool go(const T &t, const U &u) { return t != u; }
|
||||
};
|
||||
|
||||
struct add
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
@ -95,6 +136,13 @@ namespace chaiscript
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t += u)); }
|
||||
};
|
||||
|
||||
struct assign
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t.get() = u.get())); }
|
||||
};
|
||||
|
||||
struct assign_difference
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
@ -102,6 +150,49 @@ namespace chaiscript
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t -= u)); }
|
||||
};
|
||||
|
||||
struct assign_bitwise_and
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t &= u)); }
|
||||
};
|
||||
|
||||
struct assign_bitwise_or
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t |= u)); }
|
||||
};
|
||||
|
||||
struct assign_bitwise_xor
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t ^= u)); }
|
||||
};
|
||||
|
||||
struct assign_remainder
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t %= u)); }
|
||||
};
|
||||
|
||||
struct assign_bitshift_left
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t <<= u)); }
|
||||
};
|
||||
|
||||
struct assign_bitshift_right
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(T &t, const U &u) { return var(&(t >>= u)); }
|
||||
};
|
||||
|
||||
|
||||
struct pre_increment
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
@ -109,6 +200,69 @@ namespace chaiscript
|
||||
static Boxed_Value go(T &t, const U) { return var(&++t); }
|
||||
};
|
||||
|
||||
struct unary_plus
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U) { return const_var(+t); }
|
||||
};
|
||||
|
||||
struct bitwise_complement
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U) { return const_var(~t); }
|
||||
};
|
||||
|
||||
struct unary_minus
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U) { return const_var(-t); }
|
||||
};
|
||||
|
||||
struct bitwise_and
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U &u) { return const_var(t & u); }
|
||||
};
|
||||
|
||||
struct bitwise_xor
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U &u) { return const_var(t ^ u); }
|
||||
};
|
||||
|
||||
struct bitwise_or
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U &u) { return const_var(t | u); }
|
||||
};
|
||||
|
||||
struct remainder
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U &u) { return const_var(t % u); }
|
||||
};
|
||||
|
||||
struct left_shift
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U &u) { return const_var(t << u); }
|
||||
};
|
||||
|
||||
struct right_shift
|
||||
{
|
||||
static const bool lhs_const = true;
|
||||
template<typename T, typename U>
|
||||
static Boxed_Value go(const T &t, const U &u) { return const_var(t >> u); }
|
||||
};
|
||||
|
||||
struct pre_decrement
|
||||
{
|
||||
static const bool lhs_const = false;
|
||||
@ -130,12 +284,12 @@ namespace chaiscript
|
||||
return O::go(l, boxed_cast<const double &>(r.bv));
|
||||
} else if (inp_ == typeid(float)) {
|
||||
return O::go(l, boxed_cast<const float&>(r.bv));
|
||||
} else if (inp_ == typeid(long double)) {
|
||||
return O::go(l, boxed_cast<const long double&>(r.bv));
|
||||
} else if (inp_ == typeid(bool)) {
|
||||
return O::go(l, boxed_cast<const bool&>(r.bv));
|
||||
} else if (inp_ == typeid(char)) {
|
||||
return O::go(l, boxed_cast<const char&>(r.bv));
|
||||
} else if (inp_ == typeid(int)) {
|
||||
return O::go(l, boxed_cast<const int&>(r.bv));
|
||||
} else if (inp_ == typeid(unsigned int)) {
|
||||
return O::go(l, boxed_cast<const unsigned int&>(r.bv));
|
||||
} else if (inp_ == typeid(long)) {
|
||||
@ -156,6 +310,8 @@ namespace chaiscript
|
||||
return O::go(l, boxed_cast<const boost::uint16_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::uint32_t)) {
|
||||
return O::go(l, boxed_cast<const boost::uint32_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::uint64_t)) {
|
||||
return O::go(l, boxed_cast<const boost::uint64_t &>(r.bv));
|
||||
} else {
|
||||
throw boost::bad_any_cast();
|
||||
}
|
||||
@ -169,6 +325,8 @@ namespace chaiscript
|
||||
if (inp_ == typeid(double))
|
||||
{
|
||||
return oper_lhs<Ret, O>(boxed_cast<typename lhs_type<O, double>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(long double)) {
|
||||
return oper_lhs<Ret, O>(boxed_cast<typename lhs_type<O, long double>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(float)) {
|
||||
return oper_lhs<Ret, O>(boxed_cast<typename lhs_type<O, float>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(bool)) {
|
||||
@ -197,15 +355,91 @@ namespace chaiscript
|
||||
return oper_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::uint16_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::uint32_t)) {
|
||||
return oper_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::uint32_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::uint64_t)) {
|
||||
return oper_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::uint64_t>::type>(l.bv), r);
|
||||
} else {
|
||||
throw boost::bad_any_cast();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Ret, typename O, typename L>
|
||||
static Ret oper_int_lhs(L l, const Boxed_Numeric &r)
|
||||
{
|
||||
const Type_Info &inp_ = r.bv.get_type_info();
|
||||
|
||||
if (inp_ == typeid(bool)) {
|
||||
return O::go(l, boxed_cast<const bool&>(r.bv));
|
||||
} else if (inp_ == typeid(char)) {
|
||||
return O::go(l, boxed_cast<const char&>(r.bv));
|
||||
} else if (inp_ == typeid(unsigned int)) {
|
||||
return O::go(l, boxed_cast<const unsigned int&>(r.bv));
|
||||
} else if (inp_ == typeid(long)) {
|
||||
return O::go(l, boxed_cast<const long&>(r.bv));
|
||||
} else if (inp_ == typeid(unsigned long)) {
|
||||
return O::go(l, boxed_cast<const unsigned long&>(r.bv));
|
||||
} else if (inp_ == typeid(boost::int8_t)) {
|
||||
return O::go(l, boxed_cast<const boost::int8_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::int16_t)) {
|
||||
return O::go(l, boxed_cast<const boost::int16_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::int32_t)) {
|
||||
return O::go(l, boxed_cast<const boost::int32_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::int64_t)) {
|
||||
return O::go(l, boxed_cast<const boost::int64_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::uint8_t)) {
|
||||
return O::go(l, boxed_cast<const boost::uint8_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::uint16_t)) {
|
||||
return O::go(l, boxed_cast<const boost::uint16_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::uint32_t)) {
|
||||
return O::go(l, boxed_cast<const boost::uint32_t &>(r.bv));
|
||||
} else if (inp_ == typeid(boost::uint64_t)) {
|
||||
return O::go(l, boxed_cast<const boost::uint64_t &>(r.bv));
|
||||
} else {
|
||||
throw boost::bad_any_cast();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Ret, typename O>
|
||||
static Ret oper_int(const Boxed_Numeric &l, const Boxed_Numeric &r)
|
||||
{
|
||||
const Type_Info &inp_ = l.bv.get_type_info();
|
||||
|
||||
if (inp_ == typeid(bool)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, bool>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(char)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, char>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(int)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, int>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(unsigned int)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, unsigned int>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(long)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, long>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(unsigned long)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, unsigned long>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::int8_t)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::int8_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::int16_t)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::int32_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::int32_t)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::int32_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::int64_t)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::int64_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::uint8_t)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::uint8_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::uint16_t)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::uint16_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::uint32_t)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::uint32_t>::type>(l.bv), r);
|
||||
} else if (inp_ == typeid(boost::uint64_t)) {
|
||||
return oper_int_lhs<Ret, O>(boxed_cast<typename lhs_type<O, boost::uint64_t>::type>(l.bv), r);
|
||||
} else {
|
||||
throw boost::bad_any_cast();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
Boxed_Numeric(const Boxed_Value &v)
|
||||
: bv(v), d(0), i(0), isfloat(false)
|
||||
: bv(v)
|
||||
{
|
||||
const Type_Info &inp_ = v.get_type_info();
|
||||
|
||||
@ -213,45 +447,9 @@ namespace chaiscript
|
||||
{
|
||||
throw boost::bad_any_cast();
|
||||
}
|
||||
|
||||
if (inp_ == typeid(double))
|
||||
{
|
||||
d = boxed_cast<double>(v);
|
||||
isfloat = true;
|
||||
} else if (inp_ == typeid(float)) {
|
||||
d = boxed_cast<float>(v);
|
||||
isfloat = true;
|
||||
} else if (inp_ == typeid(bool)) {
|
||||
i = boxed_cast<bool>(v);
|
||||
} else if (inp_ == typeid(char)) {
|
||||
i = boxed_cast<char>(v);
|
||||
} else if (inp_ == typeid(int)) {
|
||||
i = boxed_cast<int>(v);
|
||||
} else if (inp_ == typeid(unsigned int)) {
|
||||
i = boxed_cast<unsigned int>(v);
|
||||
} else if (inp_ == typeid(long)) {
|
||||
i = boxed_cast<long>(v);
|
||||
} else if (inp_ == typeid(unsigned long)) {
|
||||
i = boxed_cast<unsigned long>(v);
|
||||
} else if (inp_ == typeid(boost::int8_t)) {
|
||||
i = boxed_cast<boost::int8_t>(v);
|
||||
} else if (inp_ == typeid(boost::int16_t)) {
|
||||
i = boxed_cast<boost::int16_t>(v);
|
||||
} else if (inp_ == typeid(boost::int32_t)) {
|
||||
i = boxed_cast<boost::int32_t>(v);
|
||||
} else if (inp_ == typeid(boost::int64_t)) {
|
||||
i = boxed_cast<boost::int64_t>(v);
|
||||
} else if (inp_ == typeid(boost::uint8_t)) {
|
||||
i = boxed_cast<boost::uint8_t>(v);
|
||||
} else if (inp_ == typeid(boost::uint16_t)) {
|
||||
i = boxed_cast<boost::uint16_t>(v);
|
||||
} else if (inp_ == typeid(boost::uint32_t)) {
|
||||
i = boxed_cast<boost::uint32_t>(v);
|
||||
} else {
|
||||
throw boost::bad_any_cast();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper<bool, equals>(*this, r);
|
||||
@ -259,27 +457,27 @@ namespace chaiscript
|
||||
|
||||
bool operator<(const Boxed_Numeric &r) const
|
||||
{
|
||||
return ((isfloat)?d:i) < ((r.isfloat)?r.d:r.i);
|
||||
return oper<bool, less_than>(*this, r);
|
||||
}
|
||||
|
||||
bool operator>(const Boxed_Numeric &r) const
|
||||
{
|
||||
return ((isfloat)?d:i) > ((r.isfloat)?r.d:r.i);
|
||||
return oper<bool, greater_than>(*this, r);
|
||||
}
|
||||
|
||||
bool operator>=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return ((isfloat)?d:i) >= ((r.isfloat)?r.d:r.i);
|
||||
return oper<bool, greater_than_equal>(*this, r);
|
||||
}
|
||||
|
||||
bool operator<=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return ((isfloat)?d:i) <= ((r.isfloat)?r.d:r.i);
|
||||
return oper<bool, less_than_equal>(*this, r);
|
||||
}
|
||||
|
||||
bool operator!=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return ((isfloat)?d:i) != ((r.isfloat)?r.d:r.i);
|
||||
return oper<bool, not_equal>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator--() const
|
||||
@ -297,39 +495,74 @@ namespace chaiscript
|
||||
return oper<Boxed_Value, add>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator+() const
|
||||
{
|
||||
return oper<Boxed_Value, unary_plus>(*this, Boxed_Value(0));
|
||||
}
|
||||
|
||||
Boxed_Value operator-() const
|
||||
{
|
||||
return oper<Boxed_Value, unary_minus>(*this, Boxed_Value(0));
|
||||
}
|
||||
|
||||
Boxed_Value operator-(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper<Boxed_Value, subtract>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator&=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper_int<Boxed_Value, assign_bitwise_and>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper<Boxed_Value, assign>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator|=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper_int<Boxed_Value, assign_bitwise_or>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator^=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper_int<Boxed_Value, assign_bitwise_xor>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator%=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper_int<Boxed_Value, assign_remainder>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator<<=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper_int<Boxed_Value, assign_bitshift_left>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator>>=(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper_int<Boxed_Value, assign_bitshift_right>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator&(const Boxed_Numeric &r) const
|
||||
{
|
||||
if (!isfloat && !r.isfloat)
|
||||
{
|
||||
return Boxed_Value(i & r.i);
|
||||
}
|
||||
return oper_int<Boxed_Value, bitwise_and>(*this, r);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("& only valid for integer types");
|
||||
Boxed_Value operator~() const
|
||||
{
|
||||
return oper_int<Boxed_Value, bitwise_complement>(*this, Boxed_Value(0));
|
||||
}
|
||||
|
||||
Boxed_Value operator^(const Boxed_Numeric &r) const
|
||||
{
|
||||
if (!isfloat && !r.isfloat)
|
||||
{
|
||||
return Boxed_Value(i ^ r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("^ only valid for integer types");
|
||||
return oper_int<Boxed_Value, bitwise_xor>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator|(const Boxed_Numeric &r) const
|
||||
{
|
||||
if (!isfloat && !r.isfloat)
|
||||
{
|
||||
return Boxed_Value(i | r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("| only valid for integer types");
|
||||
return oper_int<Boxed_Value, bitwise_or>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator*=(const Boxed_Numeric &r) const
|
||||
@ -356,58 +589,25 @@ namespace chaiscript
|
||||
|
||||
Boxed_Value operator<<(const Boxed_Numeric &r) const
|
||||
{
|
||||
if (!isfloat && !r.isfloat)
|
||||
{
|
||||
return smart_size(i << r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("<< only valid for integer types");
|
||||
return oper_int<Boxed_Value, left_shift>(*this, r);
|
||||
}
|
||||
|
||||
|
||||
Boxed_Value operator*(const Boxed_Numeric &r) const
|
||||
{
|
||||
return oper<Boxed_Value, multiply>(*this, r);
|
||||
}
|
||||
|
||||
|
||||
Boxed_Value operator%(const Boxed_Numeric &r) const
|
||||
{
|
||||
if (!isfloat && !r.isfloat)
|
||||
{
|
||||
return smart_size(i % r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast("% only valid for integer types");
|
||||
return oper_int<Boxed_Value, remainder>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value operator>>(const Boxed_Numeric &r) const
|
||||
{
|
||||
if (!isfloat && !r.isfloat)
|
||||
{
|
||||
return smart_size(i >> r.i);
|
||||
}
|
||||
|
||||
throw exception::bad_boxed_cast(">> only valid for integer types");
|
||||
return oper_int<Boxed_Value, right_shift>(*this, r);
|
||||
}
|
||||
|
||||
Boxed_Value smart_size(boost::int64_t t_i) const
|
||||
{
|
||||
if (t_i < boost::integer_traits<int>::const_min
|
||||
|| t_i > boost::integer_traits<int>::const_max)
|
||||
{
|
||||
return Boxed_Value(t_i);
|
||||
} else {
|
||||
return Boxed_Value(static_cast<int>(t_i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Boxed_Value bv;
|
||||
double d;
|
||||
boost::int64_t i;
|
||||
|
||||
bool isfloat;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
|
Loading…
x
Reference in New Issue
Block a user