diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 9b8f774..1171517 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -60,7 +60,7 @@ namespace chaiscript { private: template - static void check_divide_by_zero(T t, typename std::enable_if::value>::type* = nullptr) + static inline void check_divide_by_zero(T t, typename std::enable_if::value>::type* = nullptr) { #ifndef CHAISCRIPT_NO_PROTECT_DIVIDEBYZERO if (t == 0) { @@ -70,243 +70,223 @@ namespace chaiscript } template - static void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) + static inline void check_divide_by_zero(T, typename std::enable_if::value>::type* = nullptr) { } - struct boolean + template + static Boxed_Value boolean_go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) { - - template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) + switch (t_oper) { - switch (t_oper) - { - case Operators::equals: - return const_var(t == u); - case Operators::less_than: - return const_var(t < u); - case Operators::greater_than: - return const_var(t > u); - case Operators::less_than_equal: - return const_var(t <= u); - case Operators::greater_than_equal: - return const_var(t >= u); - case Operators::not_equal: - return const_var(t != u); - default: - throw chaiscript::detail::exception::bad_any_cast(); - } - } - }; - - struct binary - { - template - static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) - { - switch (t_oper) - { - case Operators::assign: - t = u; - break; - case Operators::pre_increment: - ++t; - break; - case Operators::pre_decrement: - --t; - break; - case Operators::assign_product: - t *= u; - break; - case Operators::assign_sum: - t += u; - break; - case Operators::assign_quotient: - check_divide_by_zero(u); - t /= u; - break; - case Operators::assign_difference: - t -= u; - break; - default: - throw chaiscript::detail::exception::bad_any_cast(); - } - - return t_lhs; - } - }; - - struct binary_int - { - template - static Boxed_Value go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) - { - switch (t_oper) - { - case Operators::assign_bitwise_and: - t &= u; - break; - case Operators::assign_bitwise_or: - t |= u; - break; - case Operators::assign_shift_left: - t <<= u; - break; - case Operators::assign_shift_right: - t >>= u; - break; - case Operators::assign_remainder: - check_divide_by_zero(u); - t %= u; - break; - case Operators::assign_bitwise_xor: - t ^= u; - break; - default: - throw chaiscript::detail::exception::bad_any_cast(); - } - return t_lhs; - } - }; - - struct const_binary_int - { - template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) - { - switch (t_oper) - { - case Operators::shift_left: - return const_var(t << u); - case Operators::shift_right: - return const_var(t >> u); - case Operators::remainder: - check_divide_by_zero(u); - return const_var(t % u); - case Operators::bitwise_and: - return const_var(t & u); - case Operators::bitwise_or: - return const_var(t | u); - case Operators::bitwise_xor: - return const_var(t ^ u); - case Operators::bitwise_complement: - return const_var(~t); - default: - throw chaiscript::detail::exception::bad_any_cast(); - } - } - }; - - struct const_binary - { - template - static Boxed_Value go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) - { - switch (t_oper) - { - case Operators::sum: - return const_var(t + u); - case Operators::quotient: - check_divide_by_zero(u); - return const_var(t / u); - case Operators::product: - return const_var(t * u); - case Operators::difference: - return const_var(t - u); - case Operators::unary_minus: - return const_var(-t); - case Operators::unary_plus: - return const_var(+t); - default: - throw chaiscript::detail::exception::bad_any_cast(); - } - } - }; - - template - struct Go - { - static Boxed_Value go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) - { - typedef typename std::common_type::type common_type; - if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) - { - return boolean::go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); - } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { - return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux_impl(t_rhs), t_lhs); - } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { - return binary_int::go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux_impl(t_rhs), t_lhs); - } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { - return const_binary_int::go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); - } else if (t_oper > Operators::const_flag) { - return const_binary::go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); - } else { + case Operators::equals: + return const_var(t == u); + case Operators::less_than: + return const_var(t < u); + case Operators::greater_than: + return const_var(t > u); + case Operators::less_than_equal: + return const_var(t <= u); + case Operators::greater_than_equal: + return const_var(t >= u); + case Operators::not_equal: + return const_var(t != u); + default: throw chaiscript::detail::exception::bad_any_cast(); - } } - }; + } + + template + static Boxed_Value binary_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) + { + switch (t_oper) + { + case Operators::assign: + t = u; + break; + case Operators::pre_increment: + ++t; + break; + case Operators::pre_decrement: + --t; + break; + case Operators::assign_product: + t *= u; + break; + case Operators::assign_sum: + t += u; + break; + case Operators::assign_quotient: + check_divide_by_zero(u); + t /= u; + break; + case Operators::assign_difference: + t -= u; + break; + default: + throw chaiscript::detail::exception::bad_any_cast(); + } + + return t_lhs; + } + + template + static Boxed_Value binary_int_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) + { + switch (t_oper) + { + case Operators::assign_bitwise_and: + t &= u; + break; + case Operators::assign_bitwise_or: + t |= u; + break; + case Operators::assign_shift_left: + t <<= u; + break; + case Operators::assign_shift_right: + t >>= u; + break; + case Operators::assign_remainder: + check_divide_by_zero(u); + t %= u; + break; + case Operators::assign_bitwise_xor: + t ^= u; + break; + default: + throw chaiscript::detail::exception::bad_any_cast(); + } + return t_lhs; + } + + template + static Boxed_Value const_binary_int_go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) + { + switch (t_oper) + { + case Operators::shift_left: + return const_var(t << u); + case Operators::shift_right: + return const_var(t >> u); + case Operators::remainder: + check_divide_by_zero(u); + return const_var(t % u); + case Operators::bitwise_and: + return const_var(t & u); + case Operators::bitwise_or: + return const_var(t | u); + case Operators::bitwise_xor: + return const_var(t ^ u); + case Operators::bitwise_complement: + return const_var(~t); + default: + throw chaiscript::detail::exception::bad_any_cast(); + } + } + + template + static Boxed_Value const_binary_go(Operators::Opers t_oper, const T &t, const U &u, const Boxed_Value &) + { + switch (t_oper) + { + case Operators::sum: + return const_var(t + u); + case Operators::quotient: + check_divide_by_zero(u); + return const_var(t / u); + case Operators::product: + return const_var(t * u); + case Operators::difference: + return const_var(t - u); + case Operators::unary_minus: + return const_var(-t); + case Operators::unary_plus: + return const_var(+t); + default: + throw chaiscript::detail::exception::bad_any_cast(); + } + } template - struct Go + static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + -> typename std::enable_if::value && !std::is_floating_point::value, Boxed_Value>::type { - static Boxed_Value go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + typedef typename std::common_type::type common_type; + if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) { - typedef typename std::common_type::type common_type; - if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) - { - return boolean::go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); - } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { - return binary::go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux_impl(t_rhs), t_lhs); - } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { - throw chaiscript::detail::exception::bad_any_cast(); - } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { - throw chaiscript::detail::exception::bad_any_cast(); - } else if (t_oper > Operators::const_flag) { - return const_binary::go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } + return boolean_go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); + } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + return binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux_impl(t_rhs), t_lhs); + } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + return binary_int_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux_impl(t_rhs), t_lhs); + } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { + return const_binary_int_go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); + } else if (t_oper > Operators::const_flag) { + return const_binary_go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); + } else { + throw chaiscript::detail::exception::bad_any_cast(); } - }; + } - template + template + static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) + -> typename std::enable_if::value || std::is_floating_point::value, Boxed_Value>::type + { + typedef typename std::common_type::type common_type; + if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) + { + return boolean_go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); + } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + return binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux_impl(t_rhs), t_lhs); + } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag) { + throw chaiscript::detail::exception::bad_any_cast(); + } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { + throw chaiscript::detail::exception::bad_any_cast(); + } else if (t_oper > Operators::const_flag) { + return const_binary_go(t_oper, get_as_aux_impl(t_lhs), get_as_aux_impl(t_rhs), t_lhs); + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + } + + template static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) { const auto &inp_ = t_rhs.get_type_info(); if (inp_ == typeid(int)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(double)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(float)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long double)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(char)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned int)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned long)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::int8_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::int16_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::int32_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::int64_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::uint8_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::uint16_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::uint32_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::uint64_t)) { - return Go::go(t_oper, t_lhs, t_rhs); + return go(t_oper, t_lhs, t_rhs); } else { throw chaiscript::detail::exception::bad_any_cast(); } @@ -317,37 +297,37 @@ namespace chaiscript const Type_Info &inp_ = t_lhs.get_type_info(); if (inp_ == typeid(int)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(double)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long double)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(float)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(char)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned int)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(long)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(unsigned long)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::int8_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::int16_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::int32_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::int64_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::uint8_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::uint16_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::uint32_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else if (inp_ == typeid(std::uint64_t)) { - return oper_rhs(t_oper, t_lhs, t_rhs); + return oper_rhs(t_oper, t_lhs, t_rhs); } else { throw chaiscript::detail::exception::bad_any_cast(); }