Changes that noexcept want to happen

This commit is contained in:
Jason Turner 2017-08-08 17:06:36 -06:00
parent 171765cfdb
commit 34534c1386
7 changed files with 192 additions and 107 deletions

View File

@ -78,22 +78,22 @@ namespace chaiscript
t().erase(this); t().erase(this);
} }
inline const T *operator->() const inline const T *operator->() const noexcept
{ {
return &(t()[this]); return &(t()[this]);
} }
inline const T &operator*() const inline const T &operator*() const noexcept
{ {
return t()[this]; return t()[this];
} }
inline T *operator->() inline T *operator->() noexcept
{ {
return &(t()[this]); return &(t()[this]);
} }
inline T &operator*() inline T &operator*() noexcept
{ {
return t()[this]; return t()[this];
} }

View File

@ -21,20 +21,11 @@ namespace chaiscript {
class bad_any_cast : public std::bad_cast class bad_any_cast : public std::bad_cast
{ {
public: public:
bad_any_cast() = default;
bad_any_cast(const bad_any_cast &) = default;
~bad_any_cast() noexcept override = default;
/// \brief Description of what error occurred /// \brief Description of what error occurred
const char * what() const noexcept override const char * what() const noexcept override
{ {
return m_what.c_str(); return "bad any cast";
} }
private:
std::string m_what = "bad any cast";
}; };
} }
@ -54,7 +45,7 @@ namespace chaiscript {
virtual void *data() noexcept = 0; virtual void *data() noexcept = 0;
const std::type_info &type() const const std::type_info &type() const noexcept
{ {
return m_type; return m_type;
} }
@ -91,7 +82,7 @@ namespace chaiscript {
public: public:
// construct/copy/destruct // construct/copy/destruct
Any() = default; Any() noexcept = default;
Any(Any &&) = default; Any(Any &&) = default;
Any &operator=(Any &&t_any) = default; Any &operator=(Any &&t_any) = default;

View File

@ -15,6 +15,7 @@
#include <typeinfo> #include <typeinfo>
#include "../chaiscript_defines.hpp" #include "../chaiscript_defines.hpp"
#include "../utility/static_string.hpp"
#include "type_info.hpp" #include "type_info.hpp"
namespace chaiscript { namespace chaiscript {
@ -34,22 +35,22 @@ namespace chaiscript
{ {
public: public:
bad_boxed_cast(Type_Info t_from, const std::type_info &t_to, bad_boxed_cast(Type_Info t_from, const std::type_info &t_to,
std::string t_what) noexcept utility::Static_String t_what) noexcept
: from(t_from), to(&t_to), m_what(std::move(t_what)) : from(t_from), to(&t_to), m_what(std::move(t_what))
{ {
} }
bad_boxed_cast(Type_Info t_from, const std::type_info &t_to) bad_boxed_cast(Type_Info t_from, const std::type_info &t_to) noexcept
: from(t_from), to(&t_to), m_what("Cannot perform boxed_cast: " + t_from.name() + " to: " + t_to.name()) : from(t_from), to(&t_to), m_what("Cannot perform boxed_cast")
{ {
} }
explicit bad_boxed_cast(std::string t_what) noexcept explicit bad_boxed_cast(utility::Static_String t_what) noexcept
: m_what(std::move(t_what)) : m_what(std::move(t_what))
{ {
} }
bad_boxed_cast(const bad_boxed_cast &) = default; bad_boxed_cast(const bad_boxed_cast &) noexcept = default;
~bad_boxed_cast() noexcept override = default; ~bad_boxed_cast() noexcept override = default;
/// \brief Description of what error occurred /// \brief Description of what error occurred
@ -62,7 +63,7 @@ namespace chaiscript
const std::type_info *to = nullptr; ///< std::type_info of the desired (but failed) result type const std::type_info *to = nullptr; ///< std::type_info of the desired (but failed) result type
private: private:
std::string m_what; utility::Static_String m_what;
}; };
} }
} }

View File

@ -199,12 +199,12 @@ namespace chaiscript
} }
} }
static void print(const std::string &s) static void print(const std::string &s) noexcept
{ {
fwrite(s.c_str(), 1, s.size(), stdout); fwrite(s.c_str(), 1, s.size(), stdout);
} }
static void println(const std::string &s) static void println(const std::string &s) noexcept
{ {
puts(s.c_str()); puts(s.c_str());
} }
@ -268,10 +268,10 @@ namespace chaiscript
} }
static bool has_guard(const Const_Proxy_Function &t_pf) static bool has_guard(const Const_Proxy_Function &t_pf) noexcept
{ {
auto pf = std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf); auto pf = std::dynamic_pointer_cast<const dispatch::Dynamic_Proxy_Function>(t_pf);
return pf && pf->get_guard(); return pf && pf->has_guard();
} }
static Const_Proxy_Function get_guard(const Const_Proxy_Function &t_pf) static Const_Proxy_Function get_guard(const Const_Proxy_Function &t_pf)
@ -302,7 +302,7 @@ namespace chaiscript
} }
static bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) static bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) noexcept
{ {
const auto pf = std::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf); const auto pf = std::dynamic_pointer_cast<const chaiscript::dispatch::Dynamic_Proxy_Function>(t_pf);
return bool(pf); return bool(pf);

View File

@ -161,29 +161,29 @@ namespace chaiscript
} }
template<typename T> template<typename T>
static Boxed_Value boolean_go(Operators::Opers t_oper, const T &t, const T &u) static bool boolean_go(Operators::Opers t_oper, const T &t, const T &u) noexcept
{ {
switch (t_oper) switch (t_oper)
{ {
case Operators::Opers::equals: case Operators::Opers::equals:
return const_var(t == u); return t == u;
case Operators::Opers::less_than: case Operators::Opers::less_than:
return const_var(t < u); return t < u;
case Operators::Opers::greater_than: case Operators::Opers::greater_than:
return const_var(t > u); return t > u;
case Operators::Opers::less_than_equal: case Operators::Opers::less_than_equal:
return const_var(t <= u); return t <= u;
case Operators::Opers::greater_than_equal: case Operators::Opers::greater_than_equal:
return const_var(t >= u); return t >= u;
case Operators::Opers::not_equal: case Operators::Opers::not_equal:
return const_var(t != u); return t != u;
default: default:
throw chaiscript::detail::exception::bad_any_cast(); assert(false);
} }
} }
template<typename T> template<typename T>
static Boxed_Value unary_go(Operators::Opers t_oper, T &t, const Boxed_Value &t_lhs) static void unary_go(Operators::Opers t_oper, T &t) noexcept
{ {
switch (t_oper) switch (t_oper)
{ {
@ -194,14 +194,13 @@ namespace chaiscript
--t; --t;
break; break;
default: default:
throw chaiscript::detail::exception::bad_any_cast(); assert(false);
} }
return t_lhs;
} }
template<typename T, typename U> template<typename T, typename U>
static Boxed_Value binary_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) static void binary_go(Operators::Opers t_oper, T &t, const U &u)
noexcept(noexcept(check_divide_by_zero(u)))
{ {
switch (t_oper) switch (t_oper)
{ {
@ -222,14 +221,12 @@ namespace chaiscript
t -= u; t -= u;
break; break;
default: default:
throw chaiscript::detail::exception::bad_any_cast(); assert(false);
} }
return t_lhs;
} }
template<typename T, typename U> template<typename T, typename U>
static Boxed_Value binary_int_go(Operators::Opers t_oper, T &t, const U &u, const Boxed_Value &t_lhs) static void binary_int_go(Operators::Opers t_oper, T &t, const U &u) noexcept
{ {
switch (t_oper) switch (t_oper)
{ {
@ -253,76 +250,77 @@ namespace chaiscript
t ^= u; t ^= u;
break; break;
default: default:
throw chaiscript::detail::exception::bad_any_cast(); assert(false);
} }
return t_lhs;
} }
template<typename T> template<typename T>
static Boxed_Value const_unary_int_go(Operators::Opers t_oper, const T &t) static auto const_unary_int_go(Operators::Opers t_oper, const T &t) noexcept
{ {
switch (t_oper) switch (t_oper)
{ {
case Operators::Opers::bitwise_complement: case Operators::Opers::bitwise_complement:
return const_var(~t); return ~t;
default: default:
throw chaiscript::detail::exception::bad_any_cast(); assert(false);
} }
} }
template<typename T> template<typename T>
static Boxed_Value const_binary_int_go(Operators::Opers t_oper, const T &t, const T &u) static auto const_binary_int_go(Operators::Opers t_oper, const T &t, const T &u)
noexcept(noexcept(check_divide_by_zero(u)))
{ {
switch (t_oper) switch (t_oper)
{ {
case Operators::Opers::shift_left: case Operators::Opers::shift_left:
return const_var(t << u); return t << u;
case Operators::Opers::shift_right: case Operators::Opers::shift_right:
return const_var(t >> u); return t >> u;
case Operators::Opers::remainder: case Operators::Opers::remainder:
check_divide_by_zero(u); check_divide_by_zero(u);
return const_var(t % u); return t % u;
case Operators::Opers::bitwise_and: case Operators::Opers::bitwise_and:
return const_var(t & u); return t & u;
case Operators::Opers::bitwise_or: case Operators::Opers::bitwise_or:
return const_var(t | u); return t | u;
case Operators::Opers::bitwise_xor: case Operators::Opers::bitwise_xor:
return const_var(t ^ u); return t ^ u;
default: default:
throw chaiscript::detail::exception::bad_any_cast(); assert(false);
} }
} }
template<typename T> template<typename T>
static Boxed_Value const_unary_go(Operators::Opers t_oper, const T &t) static auto const_unary_go(Operators::Opers t_oper, const T &t) noexcept
{ {
switch (t_oper) switch (t_oper)
{ {
case Operators::Opers::unary_minus: case Operators::Opers::unary_minus:
return const_var(-t); return -t;
case Operators::Opers::unary_plus: case Operators::Opers::unary_plus:
return const_var(+t); return +t;
default: default:
throw chaiscript::detail::exception::bad_any_cast(); assert(false);
} }
} }
template<typename T> template<typename T>
static Boxed_Value const_binary_go(Operators::Opers t_oper, const T &t, const T &u) static auto const_binary_go(Operators::Opers t_oper, const T &t, const T &u)
noexcept(noexcept(check_divide_by_zero(u)))
{ {
switch (t_oper) switch (t_oper)
{ {
case Operators::Opers::sum: case Operators::Opers::sum:
return const_var(t + u); return t + u;
case Operators::Opers::quotient: case Operators::Opers::quotient:
check_divide_by_zero(u); check_divide_by_zero(u);
return const_var(t / u); return t / u;
case Operators::Opers::product: case Operators::Opers::product:
return const_var(t * u); return t * u;
case Operators::Opers::difference: case Operators::Opers::difference:
return const_var(t - u); return t - u;
default: default:
throw chaiscript::detail::exception::bad_any_cast(); assert(false);
} }
} }
@ -331,19 +329,60 @@ namespace chaiscript
-> typename std::enable_if<!std::is_floating_point<LHS>::value && !std::is_floating_point<RHS>::value, Boxed_Value>::type -> typename std::enable_if<!std::is_floating_point<LHS>::value && !std::is_floating_point<RHS>::value, Boxed_Value>::type
{ {
typedef typename std::common_type<LHS, RHS>::type common_type; typedef typename std::common_type<LHS, RHS>::type common_type;
if (t_oper > Operators::Opers::boolean_flag && t_oper < Operators::Opers::non_const_flag)
{ switch (t_oper) {
return boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs)); case Operators::Opers::equals:
} else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { case Operators::Opers::less_than:
return binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs); case Operators::Opers::greater_than:
} else if (t_oper > Operators::Opers::non_const_int_flag && t_oper < Operators::Opers::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { case Operators::Opers::less_than_equal:
return binary_int_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs); case Operators::Opers::greater_than_equal:
} else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) { case Operators::Opers::not_equal:
return const_binary_int_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs)); return const_var(boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs)));
} else if (t_oper > Operators::Opers::const_flag) { case Operators::Opers::assign:
return const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs)); case Operators::Opers::assign_product:
} else { case Operators::Opers::assign_sum:
throw chaiscript::detail::exception::bad_any_cast(); case Operators::Opers::assign_quotient:
case Operators::Opers::assign_difference:
if (!t_lhs.is_const() && !t_lhs.is_return_value()) {
binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs));
return t_lhs;
} else {
throw chaiscript::detail::exception::bad_any_cast();
}
case Operators::Opers::assign_bitwise_and:
case Operators::Opers::assign_bitwise_or:
case Operators::Opers::assign_shift_left:
case Operators::Opers::assign_shift_right:
case Operators::Opers::assign_remainder:
case Operators::Opers::assign_bitwise_xor:
if (!t_lhs.is_const() && !t_lhs.is_return_value()) {
binary_int_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs));
return t_lhs;
} else {
throw chaiscript::detail::exception::bad_any_cast();
}
case Operators::Opers::shift_left:
case Operators::Opers::shift_right:
case Operators::Opers::remainder:
case Operators::Opers::bitwise_and:
case Operators::Opers::bitwise_or:
case Operators::Opers::bitwise_xor:
{
const auto result
= const_binary_int_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
return const_var(result);
}
case Operators::Opers::sum:
case Operators::Opers::quotient:
case Operators::Opers::product:
case Operators::Opers::difference:
{
const auto result
= const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
return const_var(result);
}
default:
throw chaiscript::detail::exception::bad_any_cast();
} }
} }
@ -352,16 +391,39 @@ namespace chaiscript
-> typename std::enable_if<std::is_floating_point<LHS>::value || std::is_floating_point<RHS>::value, Boxed_Value>::type -> typename std::enable_if<std::is_floating_point<LHS>::value || std::is_floating_point<RHS>::value, Boxed_Value>::type
{ {
typedef typename std::common_type<LHS, RHS>::type common_type; typedef typename std::common_type<LHS, RHS>::type common_type;
if (t_oper > Operators::Opers::boolean_flag && t_oper < Operators::Opers::non_const_flag)
{ switch (t_oper) {
return boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs)); case Operators::Opers::equals:
} else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { case Operators::Opers::less_than:
return binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs), t_lhs); case Operators::Opers::greater_than:
} else if (t_oper > Operators::Opers::const_flag) { case Operators::Opers::less_than_equal:
return const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs)); case Operators::Opers::greater_than_equal:
} else { case Operators::Opers::not_equal:
throw chaiscript::detail::exception::bad_any_cast(); return const_var(boolean_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs)));
case Operators::Opers::assign:
case Operators::Opers::assign_product:
case Operators::Opers::assign_sum:
case Operators::Opers::assign_quotient:
case Operators::Opers::assign_difference:
if (!t_lhs.is_const() && !t_lhs.is_return_value()) {
binary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), get_as_aux<common_type, RHS>(t_rhs));
return t_lhs;
} else {
throw chaiscript::detail::exception::bad_any_cast();
}
case Operators::Opers::sum:
case Operators::Opers::quotient:
case Operators::Opers::product:
case Operators::Opers::difference:
{
const auto result
= const_binary_go(t_oper, get_as_aux<common_type, LHS>(t_lhs), get_as_aux<common_type, RHS>(t_rhs));
return const_var(result);
}
default:
throw chaiscript::detail::exception::bad_any_cast();
} }
} }
// Unary // Unary
@ -369,27 +431,53 @@ namespace chaiscript
static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs)
-> typename std::enable_if<!std::is_floating_point<LHS>::value, Boxed_Value>::type -> typename std::enable_if<!std::is_floating_point<LHS>::value, Boxed_Value>::type
{ {
if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { switch (t_oper) {
return unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), t_lhs); case Operators::Opers::pre_increment:
} else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) { case Operators::Opers::pre_decrement:
return const_unary_int_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr())); if (!t_lhs.is_const() && !t_lhs.is_return_value()) {
} else if (t_oper > Operators::Opers::const_flag) { unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()));
return const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr())); return t_lhs;
} else { } else {
throw chaiscript::detail::exception::bad_any_cast(); throw chaiscript::detail::exception::bad_any_cast();
}
case Operators::Opers::bitwise_complement:
{
const auto val = const_unary_int_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
return const_var(val);
}
case Operators::Opers::unary_minus:
case Operators::Opers::unary_plus:
{
const auto val = const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
return const_var(val);
}
default:
throw chaiscript::detail::exception::bad_any_cast();
} }
} }
template<typename LHS> template<typename LHS>
static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs)
-> typename std::enable_if<std::is_floating_point<LHS>::value, Boxed_Value>::type -> typename std::enable_if<std::is_floating_point<LHS>::value, Boxed_Value>::type
{ {
if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { switch (t_oper) {
return unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()), t_lhs); case Operators::Opers::pre_increment:
} else if (t_oper > Operators::Opers::const_flag) { case Operators::Opers::pre_decrement:
return const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr())); if (!t_lhs.is_const() && !t_lhs.is_return_value()) {
} else { unary_go(t_oper, *static_cast<LHS *>(t_lhs.get_ptr()));
throw chaiscript::detail::exception::bad_any_cast(); return t_lhs;
} else {
throw chaiscript::detail::exception::bad_any_cast();
}
case Operators::Opers::unary_minus:
case Operators::Opers::unary_plus:
{
const auto val = const_unary_go(t_oper, *static_cast<const LHS *>(t_lhs.get_const_ptr()));
return const_var(val);
}
default:
throw chaiscript::detail::exception::bad_any_cast();
} }
} }

View File

@ -374,6 +374,10 @@ namespace chaiscript
return call_match_internal(vals, t_conversions).first; return call_match_internal(vals, t_conversions).first;
} }
bool has_guard() const noexcept
{
return bool(m_guard);
}
Proxy_Function get_guard() const Proxy_Function get_guard() const
{ {

View File

@ -20,6 +20,7 @@
#include <typeinfo> #include <typeinfo>
#include "../chaiscript_threading.hpp" #include "../chaiscript_threading.hpp"
#include "../utility/static_string.hpp"
#include "bad_boxed_cast.hpp" #include "bad_boxed_cast.hpp"
#include "boxed_cast_helper.hpp" #include "boxed_cast_helper.hpp"
#include "boxed_value.hpp" #include "boxed_value.hpp"
@ -33,7 +34,7 @@ namespace chaiscript
{ {
public: public:
bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to, bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
const std::string &t_what) noexcept const utility::Static_String &t_what) noexcept
: bad_boxed_cast(t_from, t_to, t_what) : bad_boxed_cast(t_from, t_to, t_what)
{ {
} }
@ -43,7 +44,7 @@ namespace chaiscript
{ {
} }
explicit bad_boxed_dynamic_cast(const std::string &w) noexcept explicit bad_boxed_dynamic_cast(const utility::Static_String &w) noexcept
: bad_boxed_cast(w) : bad_boxed_cast(w)
{ {
} }
@ -57,7 +58,7 @@ namespace chaiscript
{ {
public: public:
bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to, bad_boxed_type_cast(const Type_Info &t_from, const std::type_info &t_to,
const std::string &t_what) noexcept const utility::Static_String &t_what) noexcept
: bad_boxed_cast(t_from, t_to, t_what) : bad_boxed_cast(t_from, t_to, t_what)
{ {
} }
@ -67,7 +68,7 @@ namespace chaiscript
{ {
} }
explicit bad_boxed_type_cast(const std::string &w) noexcept explicit bad_boxed_type_cast(const utility::Static_String &w) noexcept
: bad_boxed_cast(w) : bad_boxed_cast(w)
{ {
} }