Merge branch 'develop' into method_missing
This commit is contained in:
@@ -303,7 +303,7 @@ namespace chaiscript
|
||||
ModulePtr sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(fun(&detail::insert_at<ContainerType>),
|
||||
[](){
|
||||
[]()->std::string{
|
||||
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
||||
return "insert_ref_at";
|
||||
} else {
|
||||
@@ -329,7 +329,7 @@ namespace chaiscript
|
||||
|
||||
typedef void (ContainerType::*push_back)(const typename ContainerType::value_type &);
|
||||
m->add(fun(static_cast<push_back>(&ContainerType::push_back)),
|
||||
[](){
|
||||
[]()->std::string{
|
||||
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
||||
return "push_back_ref";
|
||||
} else {
|
||||
@@ -357,7 +357,7 @@ namespace chaiscript
|
||||
m->add(fun(static_cast<constfrontptr>(&ContainerType::front)), "front");
|
||||
|
||||
m->add(fun(static_cast<pushptr>(&ContainerType::push_front)),
|
||||
[](){
|
||||
[]()->std::string{
|
||||
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
|
||||
return "push_front_ref";
|
||||
} else {
|
||||
@@ -418,7 +418,7 @@ namespace chaiscript
|
||||
m->add(fun(&detail::insert<ContainerType>), "insert");
|
||||
|
||||
m->add(fun(&detail::insert_ref<ContainerType>),
|
||||
[](){
|
||||
[]()->std::string{
|
||||
if (typeid(typename ContainerType::mapped_type) == typeid(Boxed_Value)) {
|
||||
return "insert_ref";
|
||||
} else {
|
||||
@@ -538,7 +538,7 @@ namespace chaiscript
|
||||
|
||||
//Special case: add push_back to string (which doesn't support other back_insertion operations
|
||||
m->add(fun(&String::push_back),
|
||||
[](){
|
||||
[]()->std::string{
|
||||
if (typeid(typename String::value_type) == typeid(Boxed_Value)) {
|
||||
return "push_back_ref";
|
||||
} else {
|
||||
|
@@ -74,46 +74,47 @@ namespace chaiscript
|
||||
template<typename Type>
|
||||
typename detail::Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions *t_conversions = nullptr)
|
||||
{
|
||||
try {
|
||||
return detail::Cast_Helper<Type>::cast(bv, t_conversions);
|
||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||
if (!t_conversions || bv.get_type_info().bare_equal(user_type<Type>()) || (t_conversions && !t_conversions->convertable_type<Type>())) {
|
||||
try {
|
||||
return detail::Cast_Helper<Type>::cast(bv, t_conversions);
|
||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CHAISCRIPT_MSVC
|
||||
//Thank you MSVC, yes we know that a constant value is being used in the if
|
||||
// statment in THIS VERSION of the template instantiation
|
||||
//Thank you MSVC, yes we know that a constant value is being used in the if
|
||||
// statment in THIS VERSION of the template instantiation
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127)
|
||||
#endif
|
||||
|
||||
if (t_conversions && t_conversions->convertable_type<Type>())
|
||||
{
|
||||
if (t_conversions && t_conversions->convertable_type<Type>())
|
||||
{
|
||||
try {
|
||||
// std::cout << "trying an up conversion " << typeid(Type).name() << '\n';
|
||||
// We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
|
||||
// either way, we are not responsible if it doesn't work
|
||||
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_type_conversion<Type>(bv), t_conversions);
|
||||
} catch (...) {
|
||||
try {
|
||||
// std::cout << "trying an up conversion " << typeid(Type).name() << '\n';
|
||||
// We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it
|
||||
// either way, we are not responsible if it doesn't work
|
||||
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_type_conversion<Type>(bv), t_conversions);
|
||||
} catch (...) {
|
||||
try {
|
||||
// std::cout << "trying a down conversion " << typeid(Type).name() << '\n';
|
||||
// try going the other way - down the inheritance graph
|
||||
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_type_down_conversion<Type>(bv), t_conversions);
|
||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||
}
|
||||
// std::cout << "trying a down conversion " << typeid(Type).name() << '\n';
|
||||
// try going the other way - down the inheritance graph
|
||||
return detail::Cast_Helper<Type>::cast(t_conversions->boxed_type_down_conversion<Type>(bv), t_conversions);
|
||||
} catch (const chaiscript::detail::exception::bad_any_cast &) {
|
||||
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||
}
|
||||
} else {
|
||||
// If it's not polymorphic, just throw the error, don't waste the time on the
|
||||
// attempted dynamic_cast
|
||||
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||
}
|
||||
} else {
|
||||
// If it's not polymorphic, just throw the error, don't waste the time on the
|
||||
// attempted dynamic_cast
|
||||
throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type));
|
||||
}
|
||||
|
||||
#ifdef CHAISCRIPT_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -641,6 +641,7 @@ namespace chaiscript
|
||||
/// \throws std::range_error if it does not
|
||||
Boxed_Value get_function_object(const std::string &t_name) const
|
||||
{
|
||||
// std::cout << "Getting function object: " << t_name << '\n';
|
||||
chaiscript::detail::threading::shared_lock<chaiscript::detail::threading::shared_mutex> l(m_mutex);
|
||||
|
||||
const auto &funs = get_function_objects_int();
|
||||
|
@@ -30,7 +30,7 @@ namespace chaiscript
|
||||
Proxy_Function build_constructor_(Class (*)(Params...))
|
||||
{
|
||||
typedef std::shared_ptr<Class> (sig)(Params...);
|
||||
return Proxy_Function(new Proxy_Function_Impl<sig>(std::function<sig>(&(constructor_<Class, Params...>))));
|
||||
return Proxy_Function(static_cast<Proxy_Function_Impl_Base *>(new Proxy_Function_Impl<sig>(std::function<sig>(&(constructor_<Class, Params...>)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -180,6 +180,8 @@ namespace chaiscript
|
||||
if (m_arity == 0)
|
||||
{
|
||||
return true;
|
||||
} else if (m_arity > 1 && m_types.size() > 1) {
|
||||
return compare_first_type(vals[0], t_conversions) && compare_type_to_param(m_types[2], vals[1], t_conversions);
|
||||
} else {
|
||||
return compare_first_type(vals[0], t_conversions);
|
||||
}
|
||||
@@ -233,14 +235,7 @@ namespace chaiscript
|
||||
|
||||
virtual bool compare_first_type(const Boxed_Value &bv, const Type_Conversions &t_conversions) const
|
||||
{
|
||||
const auto &types = get_param_types();
|
||||
|
||||
if (types.size() < 2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return compare_type_to_param(types[1], bv, t_conversions);
|
||||
return compare_type_to_param(m_types[1], bv, t_conversions);
|
||||
}
|
||||
|
||||
static bool compare_types(const std::vector<Type_Info> &tis, const std::vector<Boxed_Value> &bvs)
|
||||
@@ -779,7 +774,7 @@ namespace chaiscript
|
||||
Boxed_Value dispatch(const Funcs &funcs,
|
||||
const std::vector<Boxed_Value> &plist, const Type_Conversions &t_conversions)
|
||||
{
|
||||
|
||||
//std::cout << "starting dispatch: " << funcs.size() << '\n';
|
||||
std::multimap<size_t, const Proxy_Function_Base *> ordered_funcs;
|
||||
|
||||
for (const auto &func : funcs)
|
||||
@@ -808,11 +803,17 @@ namespace chaiscript
|
||||
for (const auto &func : ordered_funcs )
|
||||
{
|
||||
try {
|
||||
if (func.second->filter(plist, t_conversions))
|
||||
if (func.first == 0 || func.second->filter(plist, t_conversions))
|
||||
{
|
||||
return (*(func.second))(plist, t_conversions);
|
||||
}
|
||||
} catch (const exception::bad_boxed_cast &) {
|
||||
//std::cout << "Bad Boxed Cast: " << func.second->get_arity() << '(';
|
||||
//for (const auto &p : plist) {
|
||||
// std::cout << p.get_type_info().name() << ',';
|
||||
//}
|
||||
//std::cout << ")\n";
|
||||
|
||||
//parameter failed to cast, try again
|
||||
} catch (const exception::arity_error &) {
|
||||
//invalid num params, try again
|
||||
|
@@ -40,17 +40,25 @@ namespace chaiscript
|
||||
template<typename Ret, typename Class, typename ... Args>
|
||||
std::function<Ret (Class &, Args...) > to_function(Ret (Class::*func)(Args...))
|
||||
{
|
||||
#ifdef CHAISCRIPT_MSVC
|
||||
/// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for
|
||||
/// std::function for member function pointers seems to be broken in MSVC
|
||||
return std::function<Ret(Class &, Args...)>(std::mem_fn(func));
|
||||
#else
|
||||
return std::function<Ret(Class &, Args...)>(func);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Ret, typename Class, typename ... Args>
|
||||
std::function<Ret (const Class &, Args...) > to_function(Ret (Class::*func)(Args...) const)
|
||||
{
|
||||
#ifdef CHAISCRIPT_MSVC
|
||||
/// \todo this std::mem_fn wrap shouldn't be necessary but type conversions for
|
||||
/// std::function for member function pointers seems to be broken in MSVC
|
||||
return std::function<Ret (const Class &, Args...)>(std::mem_fn(func));
|
||||
return std::function<Ret(const Class &, Args...)>(std::mem_fn(func));
|
||||
#else
|
||||
return std::function<Ret(const Class &, Args...)>(func);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<bool Object>
|
||||
@@ -61,7 +69,7 @@ namespace chaiscript
|
||||
{
|
||||
/// \todo is it possible to reduce the number of templates generated here?
|
||||
return Proxy_Function(
|
||||
new Proxy_Function_Impl<typename FunctionSignature<decltype(to_function(t)) >::Signature>(to_function(t)));
|
||||
static_cast<dispatch::Proxy_Function_Impl_Base *>(new Proxy_Function_Impl<typename FunctionSignature<decltype(to_function(t)) >::Signature>(to_function(t))));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -118,7 +126,7 @@ namespace chaiscript
|
||||
template<typename T>
|
||||
Proxy_Function fun(const std::function<T> &f)
|
||||
{
|
||||
return Proxy_Function(new dispatch::Proxy_Function_Impl<T>(f));
|
||||
return Proxy_Function(static_cast<dispatch::Proxy_Function_Impl_Base *>(new dispatch::Proxy_Function_Impl<T>(f)));
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user