Merge pull request #179 from ChaiScript/lambda_type_resolution

Lambda type resolution
This commit is contained in:
Jason Turner 2015-05-20 12:30:36 -06:00
commit 2129c5318b
5 changed files with 57 additions and 65 deletions

View File

@ -57,7 +57,7 @@ namespace chaiscript
typedef typename std::remove_extent<T>::type ReturnType; typedef typename std::remove_extent<T>::type ReturnType;
const auto extent = std::extent<T>::value; const auto extent = std::extent<T>::value;
m->add(user_type<T>(), type); m->add(user_type<T>(), type);
m->add(fun<ReturnType& (T &, size_t)>( m->add(fun(
[extent](T& t, size_t index)->ReturnType &{ [extent](T& t, size_t index)->ReturnType &{
if (extent > 0 && index >= extent) { if (extent > 0 && index >= extent) {
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
@ -68,7 +68,7 @@ namespace chaiscript
), "[]" ), "[]"
); );
m->add(fun<const ReturnType& (const T &, size_t)>( m->add(fun(
[extent](const T &t, size_t index)->const ReturnType &{ [extent](const T &t, size_t index)->const ReturnType &{
if (extent > 0 && index >= extent) { if (extent > 0 && index >= extent) {
throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent)); throw std::range_error("Array index out of range. Received: " + std::to_string(index) + " expected < " + std::to_string(extent));
@ -79,7 +79,7 @@ namespace chaiscript
), "[]" ), "[]"
); );
m->add(fun<size_t (const T &)>( m->add(fun(
[extent](const T &) { [extent](const T &) {
return extent; return extent;
}), "size"); }), "size");
@ -465,7 +465,7 @@ namespace chaiscript
operators::assign<bool>(m); operators::assign<bool>(m);
operators::equal<bool>(m); operators::equal<bool>(m);
m->add(fun<std::string (const std::string &t_ss)>([](const std::string &s) -> std::string { return s; }), "to_string"); m->add(fun([](const std::string &s) -> std::string { return s; }), "to_string");
m->add(fun(&Bootstrap::bool_to_string), "to_string"); m->add(fun(&Bootstrap::bool_to_string), "to_string");
m->add(fun(&unknown_assign), "="); m->add(fun(&unknown_assign), "=");
m->add(fun(&throw_exception), "throw"); m->add(fun(&throw_exception), "throw");
@ -503,7 +503,7 @@ namespace chaiscript
m->add(fun(&ptr_assign<std::remove_const<dispatch::Proxy_Function_Base>::type>), "="); m->add(fun(&ptr_assign<std::remove_const<dispatch::Proxy_Function_Base>::type>), "=");
m->add(fun(&ptr_assign<std::add_const<dispatch::Proxy_Function_Base>::type>), "="); m->add(fun(&ptr_assign<std::add_const<dispatch::Proxy_Function_Base>::type>), "=");
m->add(chaiscript::base_class<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function>()); m->add(chaiscript::base_class<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function>());
m->add(fun<void (dispatch::Assignable_Proxy_Function &, const std::shared_ptr<const dispatch::Proxy_Function_Base> &)>( m->add(fun(
[](dispatch::Assignable_Proxy_Function &t_lhs, const std::shared_ptr<const dispatch::Proxy_Function_Base> &t_rhs) { [](dispatch::Assignable_Proxy_Function &t_lhs, const std::shared_ptr<const dispatch::Proxy_Function_Base> &t_rhs) {
t_lhs.assign(t_rhs); t_lhs.assign(t_rhs);
} }

View File

@ -252,7 +252,7 @@ namespace chaiscript
fun(std::function<typename ContainerType::reference (ContainerType *, int)> fun(std::function<typename ContainerType::reference (ContainerType *, int)>
(std::mem_fn(static_cast<indexoper>(&ContainerType::at)))), "[]"); (std::mem_fn(static_cast<indexoper>(&ContainerType::at)))), "[]");
m->add( m->add(
fun<typename ContainerType::const_reference (const ContainerType *, int)>( fun(
[](const ContainerType *c, int index) -> typename ContainerType::const_reference { [](const ContainerType *c, int index) -> typename ContainerType::const_reference {
return c->at(index); return c->at(index);
}), "[]"); }), "[]");
@ -277,9 +277,9 @@ namespace chaiscript
template<typename ContainerType> template<typename ContainerType>
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = std::make_shared<Module>()) ModulePtr container_type(const std::string &/*type*/, ModulePtr m = std::make_shared<Module>())
{ {
m->add(fun<size_t (const ContainerType *)>([](const ContainerType *a) { return a->size(); } ), "size"); m->add(fun([](const ContainerType *a) { return a->size(); } ), "size");
m->add(fun<bool (const ContainerType *)>([](const ContainerType *a) { return a->empty(); } ), "empty"); m->add(fun([](const ContainerType *a) { return a->empty(); } ), "empty");
m->add(fun<void (ContainerType *)>([](ContainerType *a) { a->clear(); } ), "clear"); m->add(fun([](ContainerType *a) { a->clear(); } ), "clear");
return m; return m;
} }
@ -547,23 +547,20 @@ namespace chaiscript
}()); }());
typedef std::function<size_t (const String *, const String &, size_t)> find_func; m->add(fun([](const String *s, const String &f, size_t pos) { return s->find(f, pos); } ), "find");
m->add(fun([](const String *s, const String &f, size_t pos) { return s->rfind(f, pos); } ), "rfind");
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_of(f, pos); } ), "find_first_of");
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_of(f, pos); } ), "find_last_of");
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_not_of(f, pos); } ), "find_last_not_of");
m->add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_not_of(f, pos); } ), "find_first_not_of");
m->add(fun([](String *s) { s->clear(); } ), "clear");
m->add(fun([](const String *s) { return s->empty(); } ), "empty");
m->add(fun([](const String *s) { return s->size(); } ), "size");
m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find(f, pos); } )), "find"); m->add(fun([](const String *s) { return s->c_str(); } ), "c_str");
m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->rfind(f, pos); } ) ), "rfind"); m->add(fun([](const String *s) { return s->data(); } ), "data");
m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find_first_of(f, pos); } ) ), "find_first_of"); m->add(fun([](const String *s, size_t pos, size_t len) { return s->substr(pos, len); } ), "substr");
m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find_last_of(f, pos); } ) ), "find_last_of");
m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find_last_not_of(f, pos); } ) ), "find_last_not_of");
m->add(fun(find_func( [](const String *s, const String &f, size_t pos) { return s->find_first_not_of(f, pos); } ) ), "find_first_not_of");
m->add(fun( std::function<void (String *)>( [](String *s) { return s->clear(); } ) ), "clear");
m->add(fun( std::function<bool (const String *)>( [](const String *s) { return s->empty(); } ) ), "empty");
m->add(fun( std::function<size_t (const String *)>( [](const String *s) { return s->size(); } ) ), "size");
m->add(fun( std::function<const char *(const String *)>( [](const String *s) { return s->c_str(); } ) ), "c_str");
m->add(fun( std::function<const char *(const String *)>( [](const String *s) { return s->data(); } ) ), "data");
m->add(fun( std::function<String (const String *, size_t, size_t)>( [](const String *s, size_t pos, size_t len) { return s->substr(pos, len); } ) ), "substr");
return m; return m;
} }
@ -577,7 +574,7 @@ namespace chaiscript
{ {
m->add(user_type<FutureType>(), type); m->add(user_type<FutureType>(), type);
m->add(fun<bool (const FutureType &)>([](const FutureType &t) { return t.valid(); }), "valid"); m->add(fun([](const FutureType &t) { return t.valid(); }), "valid");
m->add(fun(&FutureType::get), "get"); m->add(fun(&FutureType::get), "get");
m->add(fun(&FutureType::wait), "wait"); m->add(fun(&FutureType::wait), "wait");

View File

@ -54,9 +54,7 @@ namespace chaiscript
{ {
static Boxed_Value handle(const std::function<Ret> &f) { static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value( return Boxed_Value(
std::shared_ptr<dispatch::Proxy_Function_Base>( chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<Ret>>(f)
new dispatch::Proxy_Function_Impl<Ret>(f)
)
); );
} }
}; };
@ -66,10 +64,8 @@ namespace chaiscript
{ {
static Boxed_Value handle(const std::function<Ret> &f) { static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value( return Boxed_Value(
std::shared_ptr<dispatch::Proxy_Function_Base>( chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<Ret>>(f)
new Proxy_Function_Impl<Ret>(f) );
)
);
} }
}; };
@ -78,12 +74,7 @@ namespace chaiscript
{ {
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) { static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
return Boxed_Value( return Boxed_Value(
std::shared_ptr<Proxy_Function_Base>( chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
new Assignable_Proxy_Function_Impl<Ret>(
std::ref(*f),
f
)
)
); );
} }
}; };
@ -93,13 +84,8 @@ namespace chaiscript
{ {
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) { static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
return Boxed_Value( return Boxed_Value(
std::shared_ptr<Proxy_Function_Base>( chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
new Assignable_Proxy_Function_Impl<Ret>( );
std::ref(*f),
f
)
)
);
} }
}; };
@ -108,13 +94,8 @@ namespace chaiscript
{ {
static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) { static Boxed_Value handle(const std::shared_ptr<std::function<Ret>> &f) {
return Boxed_Value( return Boxed_Value(
std::shared_ptr<Proxy_Function_Base>( chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(*f),f)
new Assignable_Proxy_Function_Impl<Ret>( );
std::ref(*f),
f
)
)
);
} }
}; };
@ -123,20 +104,14 @@ namespace chaiscript
{ {
static Boxed_Value handle(std::function<Ret> &f) { static Boxed_Value handle(std::function<Ret> &f) {
return Boxed_Value( return Boxed_Value(
std::shared_ptr<Proxy_Function_Base>( chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Assignable_Proxy_Function_Impl<Ret>>(std::ref(f),
new Assignable_Proxy_Function_Impl<Ret>( std::shared_ptr<std::function<Ret>>())
std::ref(f), );
std::shared_ptr<std::function<Ret>>()
)
)
);
} }
static Boxed_Value handle(const std::function<Ret> &f) { static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value( return Boxed_Value(
std::shared_ptr<dispatch::Proxy_Function_Base>( chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<Ret>>(f)
new dispatch::Proxy_Function_Impl<Ret>(f)
)
); );
} }
}; };

View File

@ -36,6 +36,7 @@ namespace chaiscript
return std::function<Ret (Args...)>(func); return std::function<Ret (Args...)>(func);
} }
template<typename Ret, typename Class, typename ... Args> template<typename Ret, typename Class, typename ... Args>
std::function<Ret (Class &, Args...) > to_function(Ret (Class::*func)(Args...)) std::function<Ret (Class &, Args...) > to_function(Ret (Class::*func)(Args...))
{ {
@ -62,6 +63,25 @@ namespace chaiscript
#endif #endif
} }
template<typename T, typename Ret, typename Class, typename ... Args>
std::function<Ret (Args...)> to_function_callable(Ret (Class::*)(Args...), T t)
{
return std::function<Ret (Args...)>(t);
}
template<typename T, typename Ret, typename Class, typename ... Args>
std::function<Ret (Args...)> to_function_callable(Ret (Class::*)(Args...) const, T t)
{
return std::function<Ret (Args...)>(t);
}
template<typename T>
auto to_function(T t) -> decltype(to_function_callable(&T::operator(), t))
{
return to_function_callable(&T::operator(), t);
}
} }
} }

View File

@ -370,7 +370,7 @@ namespace chaiscript
// m_engine.add(fun<Boxed_Value (const dispatch::Proxy_Function_Base *, const std::vector<Boxed_Value> &)>(std::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), std::placeholders::_1, std::placeholders::_2, std::ref(m_engine.conversions()))), "call"); // m_engine.add(fun<Boxed_Value (const dispatch::Proxy_Function_Base *, const std::vector<Boxed_Value> &)>(std::bind(&chaiscript::dispatch::Proxy_Function_Base::operator(), std::placeholders::_1, std::placeholders::_2, std::ref(m_engine.conversions()))), "call");
// //
m_engine.add(fun<Boxed_Value (const dispatch::Proxy_Function_Base &, const std::vector<Boxed_Value> &)>( m_engine.add(fun(
[=](const dispatch::Proxy_Function_Base &t_fun, const std::vector<Boxed_Value> &t_params) { [=](const dispatch::Proxy_Function_Base &t_fun, const std::vector<Boxed_Value> &t_params) {
return t_fun(t_params, this->m_engine.conversions()); return t_fun(t_params, this->m_engine.conversions());
}), "call"); }), "call");
@ -378,9 +378,9 @@ namespace chaiscript
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type, std::ref(m_engine)), "type"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type, std::ref(m_engine)), "type");
m_engine.add(fun<chaiscript::Type_Info (const std::string &)>([this](const std::string &t_type_name){ return this->m_engine.get_type(t_type_name, true); }), "type"); m_engine.add(fun([this](const std::string &t_type_name){ return this->m_engine.get_type(t_type_name, true); }), "type");
m_engine.add(fun<void(const Type_Info &, const Type_Info &, const std::function<Boxed_Value(const Boxed_Value &)> &)>( m_engine.add(fun(
[=](const Type_Info &t_from, const Type_Info &t_to, const std::function<Boxed_Value (const Boxed_Value &)> &t_func) { [=](const Type_Info &t_from, const Type_Info &t_to, const std::function<Boxed_Value (const Boxed_Value &)> &t_func) {
m_engine.add(chaiscript::type_conversion(t_from, t_to, t_func)); m_engine.add(chaiscript::type_conversion(t_from, t_to, t_func));
} }