diff --git a/include/chaiscript/dispatchkit/boxed_numeric.hpp b/include/chaiscript/dispatchkit/boxed_numeric.hpp index 93bd8a2..4527579 100644 --- a/include/chaiscript/dispatchkit/boxed_numeric.hpp +++ b/include/chaiscript/dispatchkit/boxed_numeric.hpp @@ -21,63 +21,71 @@ namespace chaiscript class Boxed_Numeric { private: - template - struct choose_const + + enum opers { - typedef T& type; + boolean_flag, + equals, + less_than, + greater_than, + less_than_equal, + greater_than_equal, + not_equal, + non_const_flag, + assign, + pre_increment, + pre_decrement, + assign_product, + assign_sum, + assign_quotient, + assign_difference, + non_const_int_flag, + assign_bitwise_and, + assign_bitwise_or, + assign_shift_left, + assign_shift_right, + assign_remainder, + assign_bitwise_xor, + shift_left, + shift_right, + const_int_flag, + remainder, + bitwise_and, + bitwise_or, + bitwise_xor, + bitwise_complement, + const_flag, + sum, + quotient, + product, + difference, + unary_plus, + unary_minus }; - template - struct choose_const - { - typedef const T& type; - }; - - template - struct lhs_type - { - typedef typename choose_const::type type; - }; struct boolean { - enum oper - { - equals, - less_than, - greater_than, - less_than_equal, - greater_than_equal, - not_equal - }; - - oper m_oper; - - boolean(boolean::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = true; - #pragma GCC diagnostic ignored "-Wsign-compare" template - bool go(const T &t, const U &u) const + static Boxed_Value go(opers t_oper, const T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case equals: - return t == u; + return const_var(t == u); case less_than: - return t < u; + return const_var(t < u); case greater_than: - return t > u; + return const_var(t > u); case less_than_equal: - return t <= u; + return const_var(t <= u); case greater_than_equal: - return t >= u; + return const_var(t >= u); case not_equal: - return t != u; + return const_var(t != u); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } @@ -85,33 +93,13 @@ namespace chaiscript struct binary { - enum oper - { - assign, - pre_increment, - pre_decrement, - assign_product, - assign_sum, - assign_quotient, - assign_difference, - }; - - oper m_oper; - - binary(binary::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = false; - template - Boxed_Value go(T &t, const U &u) const + static Boxed_Value go(opers t_oper, T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case assign: - return var(&(t.get() = u.get())); + return var(&(t = u)); case pre_increment: return var(&(++t)); case pre_decrement: @@ -124,37 +112,19 @@ namespace chaiscript return var(&(t /= u)); case assign_difference: return var(&(t -= u)); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } }; - struct binary_int { - enum oper - { - assign_bitwise_and, - assign_bitwise_or, - assign_shift_left, - assign_shift_right, - assign_remainder, - assign_bitwise_xor, - }; - - oper m_oper; - - binary_int(binary_int::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = false; - template - Boxed_Value go(T &t, const U &u) const + static Boxed_Value go(opers t_oper, T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case assign_bitwise_and: return var(&(t &= u)); @@ -168,6 +138,8 @@ namespace chaiscript return var(&(t %= u)); case assign_bitwise_xor: return var(&(t ^= u)); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } @@ -175,30 +147,10 @@ namespace chaiscript struct const_binary_int { - enum oper - { - shift_left, - shift_right, - remainder, - bitwise_and, - bitwise_or, - bitwise_xor, - bitwise_complement - }; - - oper m_oper; - - const_binary_int(const_binary_int::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = true; - template - Boxed_Value go(const T &t, const U &u) const + static Boxed_Value go(opers t_oper, const T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case shift_left: return const_var(t << u); @@ -214,6 +166,8 @@ namespace chaiscript return const_var(t ^ u); case bitwise_complement: return const_var(~t); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } @@ -221,29 +175,10 @@ namespace chaiscript struct const_binary { - enum oper - { - sum, - quotient, - product, - difference, - unary_plus, - unary_minus - }; - - oper m_oper; - - const_binary(const_binary::oper t_oper) - : m_oper(t_oper) - { - } - - static const bool lhs_const = true; - template - Boxed_Value go(const T &t, const U &u) const + static Boxed_Value go(opers t_oper, const T &t, const U &u) { - switch (m_oper) + switch (t_oper) { case sum: return const_var(t + u); @@ -257,165 +192,141 @@ namespace chaiscript return const_var(-t); case unary_plus: return const_var(+t); + default: + throw boost::bad_any_cast(); } throw boost::bad_any_cast(); } }; - template - static Ret oper_lhs(const O &t_o, L l, const Boxed_Numeric &r) + template + struct Go + { + static Boxed_Value go(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) { - const Type_Info &inp_ = r.bv.get_type_info(); + if (t_oper > boolean_flag && t_oper < non_const_flag) + { + return boolean::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > non_const_flag && t_oper < non_const_int_flag) { + return binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > non_const_int_flag && t_oper < const_int_flag) { + return binary_int::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > const_int_flag && t_oper < const_flag) { + return const_binary_int::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > const_flag) { + return const_binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else { + throw boost::bad_any_cast(); + } + } + }; + + template + struct Go + { + static Boxed_Value go(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + { + if (t_oper > boolean_flag && t_oper < non_const_flag) + { + return boolean::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > non_const_flag && t_oper < non_const_int_flag) { + return binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else if (t_oper > non_const_int_flag && t_oper < const_int_flag) { + throw boost::bad_any_cast(); + } else if (t_oper > const_int_flag && t_oper < const_flag) { + throw boost::bad_any_cast(); + } else if (t_oper > const_flag) { + return const_binary::go(t_oper, boxed_cast(t_lhs.bv), boxed_cast(t_rhs.bv)); + } else { + throw boost::bad_any_cast(); + } + } + }; + + template + static Boxed_Value oper_rhs(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) + { + const Type_Info &inp_ = t_rhs.bv.get_type_info(); if (inp_ == typeid(double)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(float)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long double)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(char)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned int)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned long)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int8_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int16_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int32_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int64_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint8_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint16_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint32_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint64_t)) { - return t_o.go(l, boxed_cast(r.bv)); + return Go::go(t_oper, t_lhs, t_rhs); } else { throw boost::bad_any_cast(); } } - template - static Ret oper(const O& t_o, const Boxed_Numeric &l, const Boxed_Numeric &r) + static Boxed_Value oper(opers t_oper, const Boxed_Numeric &t_lhs, const Boxed_Numeric &t_rhs) { - const Type_Info &inp_ = l.bv.get_type_info(); + const Type_Info &inp_ = t_lhs.bv.get_type_info(); if (inp_ == typeid(double)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long double)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(float)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(char)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(int)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned int)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned long)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int8_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int16_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int32_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::int64_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint8_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint16_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint32_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(boost::uint64_t)) { - return oper_lhs(t_o, boxed_cast::type>(l.bv), r); + return oper_rhs(t_oper, t_lhs, t_rhs); } else { throw boost::bad_any_cast(); } } - template - static Ret oper_int_lhs(const O &t_o, L l, const Boxed_Numeric &r) - { - const Type_Info &inp_ = r.bv.get_type_info(); - - if (inp_ == typeid(char)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(unsigned int)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(long)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(unsigned long)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::int8_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::int16_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::int32_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::int64_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::uint8_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::uint16_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::uint32_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else if (inp_ == typeid(boost::uint64_t)) { - return t_o.go(l, boxed_cast(r.bv)); - } else { - throw boost::bad_any_cast(); - } - } - - template - static Ret oper_int(const O &t_o, const Boxed_Numeric &l, const Boxed_Numeric &r) - { - const Type_Info &inp_ = l.bv.get_type_info(); - - if (inp_ == typeid(char)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(int)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(unsigned int)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(long)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(unsigned long)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::int8_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::int16_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::int32_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::int64_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::uint8_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::uint16_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::uint32_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else if (inp_ == typeid(boost::uint64_t)) { - return oper_int_lhs(t_o, boxed_cast::type>(l.bv), r); - } else { - throw boost::bad_any_cast(); - } - }; public: Boxed_Numeric(const Boxed_Value &v) @@ -432,159 +343,159 @@ namespace chaiscript bool operator==(const Boxed_Numeric &r) const { - return oper(boolean(boolean::equals), *this, r); + return boxed_cast(oper(equals, *this, r)); } bool operator<(const Boxed_Numeric &r) const { - return oper(boolean(boolean::less_than), *this, r); + return boxed_cast(oper(less_than, *this, r)); } bool operator>(const Boxed_Numeric &r) const { - return oper(boolean(boolean::greater_than), *this, r); + return boxed_cast(oper(greater_than, *this, r)); } bool operator>=(const Boxed_Numeric &r) const { - return oper(boolean(boolean::greater_than_equal), *this, r); + return boxed_cast(oper(greater_than_equal, *this, r)); } bool operator<=(const Boxed_Numeric &r) const { - return oper(boolean(boolean::less_than_equal), *this, r); + return boxed_cast(oper(less_than_equal, *this, r)); } bool operator!=(const Boxed_Numeric &r) const { - return oper(boolean(boolean::not_equal), *this, r); + return boxed_cast(oper(not_equal, *this, r)); } Boxed_Value operator--() const { - return oper(binary(binary::pre_decrement), *this, var(0)); + return oper(pre_decrement, *this, var(0)); } Boxed_Value operator++() const { - return oper(binary(binary::pre_increment), *this, var(0)); + return oper(pre_increment, *this, var(0)); } Boxed_Value operator+(const Boxed_Numeric &r) const { - return oper(const_binary(const_binary::sum), *this, r); + return oper(sum, *this, r); } Boxed_Value operator+() const { - return oper(const_binary(const_binary::unary_plus), *this, Boxed_Value(0)); + return oper(unary_plus, *this, Boxed_Value(0)); } Boxed_Value operator-() const { - return oper(const_binary(const_binary::unary_minus), *this, Boxed_Value(0)); + return oper(unary_minus, *this, Boxed_Value(0)); } Boxed_Value operator-(const Boxed_Numeric &r) const { - return oper(const_binary(const_binary::difference), *this, r); + return oper(difference, *this, r); } Boxed_Value operator&=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_bitwise_or), *this, r); + return oper(assign_bitwise_and, *this, r); } Boxed_Value operator=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign), *this, r); + return oper(assign, *this, r); } Boxed_Value operator|=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_bitwise_or), *this, r); + return oper(assign_bitwise_or, *this, r); } Boxed_Value operator^=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_bitwise_xor), *this, r); + return oper(assign_bitwise_xor, *this, r); } Boxed_Value operator%=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_remainder), *this, r); + return oper(assign_remainder, *this, r); } Boxed_Value operator<<=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_shift_left), *this, r); + return oper(assign_shift_left, *this, r); } Boxed_Value operator>>=(const Boxed_Numeric &r) const { - return oper_int(binary_int(binary_int::assign_shift_right), *this, r); + return oper(assign_shift_right, *this, r); } Boxed_Value operator&(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::bitwise_and), *this, r); + return oper(bitwise_and, *this, r); } Boxed_Value operator~() const { - return oper_int(const_binary_int(const_binary_int::bitwise_complement), *this, Boxed_Value(0)); + return oper(bitwise_complement, *this, Boxed_Value(0)); } Boxed_Value operator^(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::bitwise_xor), *this, r); + return oper(bitwise_xor, *this, r); } Boxed_Value operator|(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::bitwise_or), *this, r); + return oper(bitwise_or, *this, r); } Boxed_Value operator*=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign_product), *this, r); + return oper(assign_product, *this, r); } Boxed_Value operator/=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign_quotient), *this, r); + return oper(assign_quotient, *this, r); } Boxed_Value operator+=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign_sum), *this, r); + return oper(assign_sum, *this, r); } Boxed_Value operator-=(const Boxed_Numeric &r) const { - return oper(binary(binary::assign_difference), *this, r); + return oper(assign_difference, *this, r); } Boxed_Value operator/(const Boxed_Numeric &r) const { - return oper(const_binary(const_binary::quotient), *this, r); + return oper(quotient, *this, r); } Boxed_Value operator<<(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::shift_left), *this, r); + return oper(shift_left, *this, r); } Boxed_Value operator*(const Boxed_Numeric &r) const { - return oper(const_binary(const_binary::product), *this, r); + return oper(product, *this, r); } Boxed_Value operator%(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::remainder), *this, r); + return oper(remainder, *this, r); } Boxed_Value operator>>(const Boxed_Numeric &r) const { - return oper_int(const_binary_int(const_binary_int::shift_right), *this, r); + return oper(shift_right, *this, r); } Boxed_Value bv;