diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 7c59366..b191892 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -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 - 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 - P1 construct_pod(Boxed_Numeric v) + boost::shared_ptr construct_pod(Boxed_Numeric v) { - if (v.isfloat) - { - return P1(v.d); - } else { - return P1(v.i); - } + boost::shared_ptr 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 - 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 - 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 - 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 - 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 - 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 - 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 + ModulePtr copy_constructor(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(constructor(), 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 - ModulePtr opers_integer_arithmetic(ModulePtr m = ModulePtr(new Module())) - { - operators::assign_bitwise_and(m); - operators::assign_xor(m); - operators::assign_bitwise_or(m); -// operators::assign_difference(m); - operators::assign_left_shift(m); -// operators::assign_product(m); -// operators::assign_quotient(m); -// operators::assign_remainder(m); - operators::assign_right_shift(m); -// operators::assign_sum(m); - -// operators::prefix_decrement(m); -// operators::prefix_increment(m); -// operators::addition(m); - operators::unary_plus(m); -// operators::subtraction(m); - operators::unary_minus(m); - operators::bitwise_and(m); - operators::bitwise_compliment(m); - operators::bitwise_xor(m); - operators::bitwise_or(m); -// operators::division(m); - operators::left_shift(m); -// operators::multiplication(m); - operators::remainder(m); - operators::right_shift(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 - ModulePtr opers_float_arithmetic(ModulePtr m = ModulePtr(new Module())) - { -// operators::assign_difference(m); -// operators::assign_product(m); -// operators::assign_quotient(m); -// operators::assign_sum(m); - -// operators::addition(m); - operators::unary_plus(m); -// operators::subtraction(m); - operators::unary_minus(m); -// operators::division(m); -// operators::multiplication(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 - ModulePtr copy_constructor(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(constructor(), 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 - ModulePtr oper_assign_pod(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&detail::assign_pod), "="); - 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(), name); - basic_constructors(name, m); - operators::assign(m); - oper_assign_pod(m); + m->add(constructor(), name); construct_pod(name, m); -// m->add(fun(&detail::assign_sum_pod), "+="); -// m->add(fun(&detail::assign_difference_pod), "-="); -// m->add(fun(&detail::assign_product_pod), "*="); -// m->add(fun(&detail::assign_quotient_pod), "/="); - m->add(fun(&to_string), "to_string"); m->add(fun(&parse_string), "to_" + name); return m; } - /** - * Add all common functions for a POD type. All operators, and - * common conversions - */ - template - ModulePtr bootstrap_integer_type(const std::string &name, ModulePtr m = ModulePtr(new Module())) - { - bootstrap_pod_type(name, m); - - m->add(fun(&detail::assign_bitwise_and_pod), "&="); - m->add(fun(&detail::assign_xor_pod), "^="); - m->add(fun(&detail::assign_bitwise_or_pod), "|="); - m->add(fun(&detail::assign_left_shift_pod), "<<="); - m->add(fun(&detail::assign_remainder_pod), "%="); - m->add(fun(&detail::assign_right_shift_pod), ">>="); - - opers_integer_arithmetic(m); - return m; - } - - /** - * Add all common functions for a POD type. All operators, and - * common conversions - */ - template - ModulePtr bootstrap_float_type(const std::string &name, ModulePtr m = ModulePtr(new Module())) - { - bootstrap_pod_type(name, m); - opers_float_arithmetic(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), "+"); - m->add(fun(&operators::subtraction), "-"); - m->add(fun(&operators::bitwise_and), "&"); - m->add(fun(&operators::bitwise_xor), "^"); - m->add(fun(&operators::bitwise_or), "|"); - m->add(fun(&operators::division), "/"); - m->add(fun(&operators::left_shift), "<<"); - m->add(fun(&operators::multiplication), "*"); - m->add(fun(&operators::remainder), "%"); - m->add(fun(&operators::right_shift), ">>"); + 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_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_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", m); - bootstrap_integer_type("int", m); - bootstrap_integer_type("size_t", m); - bootstrap_integer_type("char", m); - bootstrap_integer_type("int64_t", m); + bootstrap_pod_type("double", m); + bootstrap_pod_type("long_double", m); + bootstrap_pod_type("float", m); + bootstrap_pod_type("int", m); + bootstrap_pod_type("unsigned_int", m); + bootstrap_pod_type("unsigned_long", m); + bootstrap_pod_type("size_t", m); + bootstrap_pod_type("char", m); + bootstrap_pod_type("int8_t", m); + bootstrap_pod_type("int16_t", m); + bootstrap_pod_type("int32_t", m); + bootstrap_pod_type("int64_t", m); + bootstrap_pod_type("uint8_t", m); + bootstrap_pod_type("uint16_t", m); + bootstrap_pod_type("uint32_t", m); + bootstrap_pod_type("uint64_t", m); operators::logical_compliment(m); - opers_comparison(m); opers_arithmetic_pod(m); diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 1c40640..1e23005 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -42,10 +42,51 @@ namespace chaiscript struct equals { static const bool lhs_const = true; +#pragma GCC diagnostic ignored "-Wsign-compare" template 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 + 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 + 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 + 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 + 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 + 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 + 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 + static Boxed_Value go(T &t, const U &u) { return var(&(t &= u)); } + }; + + struct assign_bitwise_or + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t |= u)); } + }; + + struct assign_bitwise_xor + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t ^= u)); } + }; + + struct assign_remainder + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t %= u)); } + }; + + struct assign_bitshift_left + { + static const bool lhs_const = false; + template + static Boxed_Value go(T &t, const U &u) { return var(&(t <<= u)); } + }; + + struct assign_bitshift_right + { + static const bool lhs_const = false; + template + 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 + static Boxed_Value go(const T &t, const U) { return const_var(+t); } + }; + + struct bitwise_complement + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U) { return const_var(~t); } + }; + + struct unary_minus + { + static const bool lhs_const = true; + template + static Boxed_Value go(const T &t, const U) { return const_var(-t); } + }; + + struct bitwise_and + { + static const bool lhs_const = true; + template + 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 + 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 + static Boxed_Value go(const T &t, const U &u) { return const_var(t | u); } + }; + + struct remainder + { + static const bool lhs_const = true; + template + 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 + 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 + 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(r.bv)); } else if (inp_ == typeid(float)) { return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(long double)) { + return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(bool)) { return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(char)) { return O::go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(int)) { - return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(unsigned int)) { return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(long)) { @@ -156,6 +310,8 @@ namespace chaiscript return O::go(l, boxed_cast(r.bv)); } else if (inp_ == typeid(boost::uint32_t)) { return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint64_t)) { + return O::go(l, boxed_cast(r.bv)); } else { throw boost::bad_any_cast(); } @@ -169,6 +325,8 @@ namespace chaiscript if (inp_ == typeid(double)) { return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(long double)) { + return oper_lhs(boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(float)) { return oper_lhs(boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(bool)) { @@ -197,15 +355,91 @@ namespace chaiscript return oper_lhs(boxed_cast::type>(l.bv), r); } else if (inp_ == typeid(boost::uint32_t)) { return oper_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint64_t)) { + return oper_lhs(boxed_cast::type>(l.bv), r); + } else { + throw boost::bad_any_cast(); + } + } + + + template + 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(r.bv)); + } else if (inp_ == typeid(char)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(unsigned int)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(long)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(unsigned long)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int8_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int16_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int32_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::int64_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint8_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint16_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint32_t)) { + return O::go(l, boxed_cast(r.bv)); + } else if (inp_ == typeid(boost::uint64_t)) { + return O::go(l, boxed_cast(r.bv)); + } else { + throw boost::bad_any_cast(); + } + } + + template + 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(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(char)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(int)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(unsigned int)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(long)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(unsigned long)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int8_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int16_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int32_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::int64_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint8_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint16_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint32_t)) { + return oper_int_lhs(boxed_cast::type>(l.bv), r); + } else if (inp_ == typeid(boost::uint64_t)) { + return oper_int_lhs(boxed_cast::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(v); - isfloat = true; - } else if (inp_ == typeid(float)) { - d = boxed_cast(v); - isfloat = true; - } else if (inp_ == typeid(bool)) { - i = boxed_cast(v); - } else if (inp_ == typeid(char)) { - i = boxed_cast(v); - } else if (inp_ == typeid(int)) { - i = boxed_cast(v); - } else if (inp_ == typeid(unsigned int)) { - i = boxed_cast(v); - } else if (inp_ == typeid(long)) { - i = boxed_cast(v); - } else if (inp_ == typeid(unsigned long)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int8_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int16_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int32_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::int64_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint8_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint16_t)) { - i = boxed_cast(v); - } else if (inp_ == typeid(boost::uint32_t)) { - i = boxed_cast(v); - } else { - throw boost::bad_any_cast(); - } } + bool operator==(const Boxed_Numeric &r) const { return oper(*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(*this, r); } bool operator>(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) > ((r.isfloat)?r.d:r.i); + return oper(*this, r); } bool operator>=(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) >= ((r.isfloat)?r.d:r.i); + return oper(*this, r); } bool operator<=(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) <= ((r.isfloat)?r.d:r.i); + return oper(*this, r); } bool operator!=(const Boxed_Numeric &r) const { - return ((isfloat)?d:i) != ((r.isfloat)?r.d:r.i); + return oper(*this, r); } Boxed_Value operator--() const @@ -297,39 +495,74 @@ namespace chaiscript return oper(*this, r); } + Boxed_Value operator+() const + { + return oper(*this, Boxed_Value(0)); + } + + Boxed_Value operator-() const + { + return oper(*this, Boxed_Value(0)); + } + Boxed_Value operator-(const Boxed_Numeric &r) const { return oper(*this, r); } + Boxed_Value operator&=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator=(const Boxed_Numeric &r) const + { + return oper(*this, r); + } + + Boxed_Value operator|=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator^=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator%=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator<<=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + + Boxed_Value operator>>=(const Boxed_Numeric &r) const + { + return oper_int(*this, r); + } + Boxed_Value operator&(const Boxed_Numeric &r) const { - if (!isfloat && !r.isfloat) - { - return Boxed_Value(i & r.i); - } + return oper_int(*this, r); + } - throw exception::bad_boxed_cast("& only valid for integer types"); + Boxed_Value operator~() const + { + return oper_int(*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(*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(*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(*this, r); } - Boxed_Value operator*(const Boxed_Numeric &r) const { return oper(*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(*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(*this, r); } - Boxed_Value smart_size(boost::int64_t t_i) const - { - if (t_i < boost::integer_traits::const_min - || t_i > boost::integer_traits::const_max) - { - return Boxed_Value(t_i); - } else { - return Boxed_Value(static_cast(t_i)); - } - } - - Boxed_Value bv; - double d; - boost::int64_t i; - - bool isfloat; }; namespace detail