Merge remote-tracking branch 'origin/remove_std_function' into develop

Conflicts:
	include/chaiscript/dispatchkit/boxed_number.hpp
This commit is contained in:
Jason Turner 2015-06-08 14:34:02 -06:00
commit d4e22c2c2c
14 changed files with 227 additions and 210 deletions

View File

@ -18,6 +18,7 @@
#include "dispatchkit/bootstrap.hpp"
#include "dispatchkit/bootstrap_stl.hpp"
#include "dispatchkit/boxed_value.hpp"
#include "language/chaiscript_prelude.chai"
#ifndef CHAISCRIPT_NO_THREADS
#include <future>
@ -47,9 +48,11 @@ namespace chaiscript
#ifndef CHAISCRIPT_NO_THREADS
lib->add(standard_library::future_type<std::future<chaiscript::Boxed_Value>>("future"));
lib->add(chaiscript::fun<std::future<Boxed_Value> (const std::function<chaiscript::Boxed_Value ()> &)>([](const std::function<chaiscript::Boxed_Value ()> &t_func){ return std::async(std::launch::async, t_func);}), "async");
lib->add(chaiscript::fun([](const std::function<chaiscript::Boxed_Value ()> &t_func){ return std::async(std::launch::async, t_func);}), "async");
#endif
lib->eval(ChaiScript_Prelude::chaiscript_prelude() /*, "standard prelude"*/ );
return lib;
}

View File

@ -243,18 +243,18 @@ namespace chaiscript
template<typename ContainerType>
ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = std::make_shared<Module>())
{
// cppcheck-suppress syntaxError
typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t);
//In the interest of runtime safety for the m, we prefer the at() method for [] access,
//to throw an exception in an out of bounds condition.
m->add(
fun(std::function<typename ContainerType::reference (ContainerType *, int)>
(std::mem_fn(static_cast<indexoper>(&ContainerType::at)))), "[]");
fun(
[](ContainerType &c, int index) -> typename ContainerType::reference {
return c.at(index);
}), "[]");
m->add(
fun(
[](const ContainerType *c, int index) -> typename ContainerType::const_reference {
return c->at(index);
[](const ContainerType &c, int index) -> typename ContainerType::const_reference {
return c.at(index);
}), "[]");
return m;

View File

@ -251,7 +251,7 @@ namespace chaiscript
}
template<typename LHS>
static Boxed_Value oper_rhs(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
inline 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();
@ -292,7 +292,7 @@ namespace chaiscript
}
}
static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
inline static Boxed_Value oper(Operators::Opers t_oper, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs)
{
const Type_Info &inp_ = t_lhs.get_type_info();

View File

@ -0,0 +1,96 @@
// This file is distributed under the BSD License.
// See "license.txt" for details.
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
// Copyright 2009-2015, Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_CALLABLE_TRAITS_HPP_
#define CHAISCRIPT_CALLABLE_TRAITS_HPP_
#include <memory>
namespace chaiscript {
namespace dispatch {
namespace detail {
template<typename Class, typename ... Param>
struct Constructor
{
template<typename ... Inner>
std::shared_ptr<Class> operator()(Inner&& ... inner) const {
return std::make_shared<Class>(std::forward<Inner>(inner)...);
}
};
template<typename Ret, typename Class, typename ... Param>
struct Const_Caller
{
Const_Caller(Ret (Class::*t_func)(Param...) const) : m_func(t_func) {}
template<typename ... Inner>
Ret operator()(const Class &o, Inner&& ... inner) const {
return (o.*m_func)(std::forward<Inner>(inner)...);
}
Ret (Class::*m_func)(Param...) const;
};
template<typename Ret, typename ... Param>
struct Fun_Caller
{
Fun_Caller(Ret( * t_func)(Param...) ) : m_func(t_func) {}
template<typename ... Inner>
Ret operator()(Inner&& ... inner) const {
return (m_func)(std::forward<Inner>(inner)...);
}
Ret(*m_func)(Param...);
};
template<typename Ret, typename Class, typename ... Param>
struct Caller
{
Caller(Ret (Class::*t_func)(Param...)) : m_func(t_func) {}
template<typename ... Inner>
Ret operator()(Class &o, Inner&& ... inner) const {
return (o.*m_func)(std::forward<Inner>(inner)...);
}
Ret (Class::*m_func)(Param...);
};
template<typename T>
struct Function_Signature
{
};
template<typename Ret, typename ... Params>
struct Function_Signature<Ret (Params...)>
{
typedef Ret Return_Type;
typedef Ret (Signature)(Params...);
};
template<typename Ret, typename T, typename ... Params>
struct Function_Signature<Ret (T::*)(Params...) const>
{
typedef Ret Return_Type;
typedef Ret (Signature)(Params...);
};
template<typename T>
struct Callable_Traits
{
typedef typename Function_Signature<decltype(&T::operator())>::Signature Signature;
typedef typename Function_Signature<decltype(&T::operator())>::Return_Type Return_Type;
};
}
}
}
#endif

View File

@ -95,6 +95,7 @@ namespace chaiscript
template<typename Ret, typename ... Params>
std::function<Ret (Params...)> build_function_caller_helper(Ret (Params...), const std::vector<Const_Proxy_Function> &funcs, const Type_Conversions *t_conversions)
{
/*
if (funcs.size() == 1)
{
std::shared_ptr<const Proxy_Function_Impl<Ret (Params...)>> pfi =
@ -108,6 +109,7 @@ namespace chaiscript
// looks like this either wasn't a Proxy_Function_Impl or the types didn't match
// we cannot make any other guesses or assumptions really, so continuing
}
*/
return std::function<Ret (Params...)>(Build_Function_Caller_Helper<Ret, Params...>(funcs, t_conversions?*t_conversions:Type_Conversions()));
}

View File

@ -9,7 +9,6 @@
#include <functional>
#include <memory>
#include <string>
#include <type_traits>
#include "boxed_number.hpp"
@ -23,7 +22,7 @@ namespace chaiscript
{
namespace dispatch
{
template<class T> class Proxy_Function_Impl;
template<class T, class U> class Proxy_Function_Callable_Impl;
template<class T> class Assignable_Proxy_Function_Impl;
namespace detail
@ -54,7 +53,7 @@ namespace chaiscript
{
static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<Ret>>(f)
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
);
}
};
@ -64,7 +63,7 @@ namespace chaiscript
{
static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<Ret>>(f)
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
);
}
};
@ -111,7 +110,7 @@ namespace chaiscript
static Boxed_Value handle(const std::function<Ret> &f) {
return Boxed_Value(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<Ret>>(f)
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret, std::function<Ret>>>(f)
);
}
};

View File

@ -16,21 +16,14 @@ namespace chaiscript
{
namespace detail
{
/**
* A constructor function, used for creating a new object
* of a given type with a given set of params
*/
template<typename Class, typename ... Params>
std::shared_ptr<Class> constructor_(Params ... params)
{
return std::make_shared<Class>(params...);
}
template<typename Class, typename ... Params >
Proxy_Function build_constructor_(Class (*)(Params...))
{
typedef std::shared_ptr<Class> (sig)(Params...);
return Proxy_Function(static_cast<Proxy_Function_Impl_Base *>(new Proxy_Function_Impl<sig>(std::function<sig>(&(constructor_<Class, Params...>)))));
auto call = dispatch::detail::Constructor<Class, Params...>();
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<std::shared_ptr<Class> (Params...), decltype(call)>>(call));
}
}
}

View File

@ -549,48 +549,44 @@ namespace chaiscript
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const = 0;
};
/// The standard typesafe function call implementation of Proxy_Function
/// It takes a std::function<> object and performs runtime
/// type checking of Boxed_Value parameters, in a type safe manner
template<typename Func>
class Proxy_Function_Impl : public Proxy_Function_Impl_Base
/// For any callable object
template<typename Func, typename Callable>
class Proxy_Function_Callable_Impl : public Proxy_Function_Impl_Base
{
public:
Proxy_Function_Impl(std::function<Func> f)
Proxy_Function_Callable_Impl(Callable f)
: Proxy_Function_Impl_Base(detail::build_param_type_list(static_cast<Func *>(nullptr))),
m_f(std::move(f)), m_dummy_func(nullptr)
m_f(std::move(f))
{
}
virtual ~Proxy_Function_Impl() {}
virtual ~Proxy_Function_Callable_Impl() {}
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{
return detail::compare_types_cast(m_dummy_func, vals, t_conversions);
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
}
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
{
return dynamic_cast<const Proxy_Function_Impl<Func> *>(&t_func) != nullptr;
return dynamic_cast<const Proxy_Function_Callable_Impl<Func, Callable> *>(&t_func) != nullptr;
}
std::function<Func> internal_function() const
{
return m_f;
}
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{
return detail::Do_Call<typename std::function<Func>::result_type>::go(m_f, params, t_conversions);
typedef typename detail::Function_Signature<Func>::Return_Type Return_Type;
return detail::Do_Call<Return_Type>::template go<Func>(m_f, params, t_conversions);
}
private:
std::function<Func> m_f;
Func *m_dummy_func;
Callable m_f;
};
class Assignable_Proxy_Function : public Proxy_Function_Impl_Base
{
public:
@ -613,17 +609,16 @@ namespace chaiscript
public:
Assignable_Proxy_Function_Impl(std::reference_wrapper<std::function<Func>> t_f, std::shared_ptr<std::function<Func>> t_ptr)
: Assignable_Proxy_Function(detail::build_param_type_list(static_cast<Func *>(nullptr))),
m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_ptr)), m_dummy_func(nullptr)
m_f(std::move(t_f)), m_shared_ptr_holder(std::move(t_ptr))
{
assert(!m_shared_ptr_holder || m_shared_ptr_holder.get() == &m_f.get());
}
virtual ~Assignable_Proxy_Function_Impl() {}
virtual bool compare_types_with_cast(const std::vector<Boxed_Value> &vals, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{
return detail::compare_types_cast(m_dummy_func, vals, t_conversions);
return detail::compare_types_cast(static_cast<Func *>(nullptr), vals, t_conversions);
}
virtual bool operator==(const Proxy_Function_Base &t_func) const CHAISCRIPT_OVERRIDE
@ -643,14 +638,13 @@ namespace chaiscript
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{
return detail::Do_Call<typename std::function<Func>::result_type>::go(m_f.get(), params, t_conversions);
return detail::Do_Call<typename std::function<Func>::result_type>::template go<Func>(m_f.get(), params, t_conversions);
}
private:
std::reference_wrapper<std::function<Func>> m_f;
std::shared_ptr<std::function<Func>> m_shared_ptr_holder;
Func *m_dummy_func;
};
/// Attribute getter Proxy_Function implementation
template<typename T, typename Class>

View File

@ -16,6 +16,7 @@
#include "boxed_value.hpp"
#include "handle_return.hpp"
#include "type_info.hpp"
#include "callable_traits.hpp"
namespace chaiscript {
class Type_Conversions;
@ -68,6 +69,7 @@ namespace chaiscript
#ifdef CHAISCRIPT_GCC_4_6
/// \todo REMOVE THIS WHEN WE DROP G++4.6
// Forward declaration
template<typename ... Rest>
struct Try_Cast;
@ -100,7 +102,7 @@ namespace chaiscript
template<typename Ret, typename ... Params>
bool compare_types_cast(Ret (*)(Params...),
const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{
{
try {
Try_Cast<Params...>::do_try(params, 0, t_conversions);
} catch (const exception::bad_boxed_cast &) {
@ -114,8 +116,8 @@ namespace chaiscript
struct Call_Func
{
template<typename ... InnerParams>
static Ret do_call(const std::function<Ret (Params...)> &f,
template<typename Callable, typename ... InnerParams>
static Ret do_call(const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
{
return Call_Func<Ret, count - 1, Params...>::do_call(f, params, t_conversions, std::forward<InnerParams>(innerparams)..., params[sizeof...(Params) - count]);
@ -129,8 +131,8 @@ namespace chaiscript
#pragma warning(push)
#pragma warning(disable : 4100) /// Disable unreferenced formal parameter warning, which only shows up in MSVC I don't think there's any way around it \todo evaluate this
#endif
template<typename ... InnerParams>
static Ret do_call(const std::function<Ret (Params...)> &f,
template<typename Callable, typename ... InnerParams>
static Ret do_call(const Callable &f,
const std::vector<Boxed_Value> &, const Type_Conversions &t_conversions, InnerParams &&... innerparams)
{
return f(boxed_cast<Params>(std::forward<InnerParams>(innerparams), &t_conversions)...);
@ -146,8 +148,8 @@ namespace chaiscript
* if any unboxing fails the execution of the function fails and
* the bad_boxed_cast is passed up to the caller.
*/
template<typename Ret, typename ... Params>
Ret call_func(const std::function<Ret (Params...)> &f,
template<typename Callable, typename Ret, typename ... Params>
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{
if (params.size() == sizeof...(Params))
@ -158,6 +160,8 @@ namespace chaiscript
throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
}
#else
template<size_t ... I>
@ -206,8 +210,9 @@ namespace chaiscript
return compare_types_cast(indexes(), f, params, t_conversions);
}
template<typename Ret, typename ... Params, size_t ... I>
Ret call_func(Indexes<I...>, const std::function<Ret (Params...)> &f,
template<typename Callable, typename Ret, typename ... Params, size_t ... I>
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &, Indexes<I...>, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{
(void)params; (void)t_conversions;
@ -221,17 +226,12 @@ namespace chaiscript
* if any unboxing fails the execution of the function fails and
* the bad_boxed_cast is passed up to the caller.
*/
template<typename Ret, typename ... Params>
Ret call_func(const std::function<Ret (Params...)> &f,
template<typename Callable, typename Ret, typename ... Params>
Ret call_func(const chaiscript::dispatch::detail::Function_Signature<Ret (Params...)> &sig, const Callable &f,
const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{
if (params.size() == sizeof...(Params))
{
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
return call_func(indexes(), f, params, t_conversions);
}
throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
typedef typename Make_Indexes<sizeof...(Params)>::indexes indexes;
return call_func(sig, indexes(), f, params, t_conversions);
}
#endif
@ -251,20 +251,20 @@ namespace chaiscript
template<typename Ret>
struct Do_Call
{
template<typename Fun>
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
template<typename Signature, typename Callable>
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{
return Handle_Return<Ret>::handle(call_func(fun, params, t_conversions));
return Handle_Return<Ret>::handle(call_func(Function_Signature<Signature>(), fun, params, t_conversions));
}
};
template<>
struct Do_Call<void>
{
template<typename Fun>
static Boxed_Value go(const std::function<Fun> &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
template<typename Signature, typename Callable>
static Boxed_Value go(const Callable &fun, const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions)
{
call_func(fun, params, t_conversions);
call_func(Function_Signature<Signature>(), fun, params, t_conversions);
return Handle_Return<void>::handle();
}
};

View File

@ -7,7 +7,6 @@
#ifndef CHAISCRIPT_REGISTER_FUNCTION_HPP_
#define CHAISCRIPT_REGISTER_FUNCTION_HPP_
#include <functional>
#include <type_traits>
#include "bind_first.hpp"
@ -15,75 +14,6 @@
namespace chaiscript
{
namespace dispatch
{
namespace detail
{
template<typename T>
struct FunctionSignature
{
};
template<typename Sig>
struct FunctionSignature<std::function<Sig> >
{
typedef Sig Signature;
};
template<typename Ret, typename ... Args>
std::function<Ret (Args...) > to_function(Ret (*func)(Args...))
{
return std::function<Ret (Args...)>(func);
}
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)
{
#if defined(CHAISCRIPT_MSVC) || defined(CHAISCRIPT_LIBCPP)
/// \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...)>([func](const Class &o, Args... args)->Ret {
return (o.*func)(std::forward<Args>(args)...);
});
#else
return std::function<Ret(const Class &, Args...)>(func);
#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);
}
}
}
/// \brief Creates a new Proxy_Function object from a free function, member function or data member
/// \param[in] t Function / member to expose
@ -108,22 +38,39 @@ namespace chaiscript
template<typename T>
Proxy_Function fun(const T &t)
{
typedef typename dispatch::detail::Callable_Traits<T>::Signature Signature;
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<typename dispatch::detail::FunctionSignature<decltype(dispatch::detail::to_function(t)) >::Signature>>(dispatch::detail::to_function(t)));
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Signature, T>>(t));
}
template<typename Ret, typename ... Param>
Proxy_Function fun(Ret (*func)(Param...))
{
auto fun_call = dispatch::detail::Fun_Caller<Ret, Param...>(func);
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (Param...), decltype(fun_call)>>(fun_call));
}
template<typename Ret, typename Class, typename ... Param>
Proxy_Function fun(Ret (Class::*func)(Param...) const)
Proxy_Function fun(Ret (Class::*t_func)(Param...) const)
{
auto call = dispatch::detail::Const_Caller<Ret, Class, Param...>(t_func);
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<typename dispatch::detail::FunctionSignature<decltype(dispatch::detail::to_function(func)) >::Signature>>(dispatch::detail::to_function(func)));
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (const Class &, Param...), decltype(call)>>(call));
}
template<typename Ret, typename Class, typename ... Param>
Proxy_Function fun(Ret (Class::*func)(Param...))
Proxy_Function fun(Ret (Class::*t_func)(Param...))
{
auto call = dispatch::detail::Caller<Ret, Class, Param...>(t_func);
return Proxy_Function(
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<typename dispatch::detail::FunctionSignature<decltype(dispatch::detail::to_function(func)) >::Signature>>(dispatch::detail::to_function(func)));
chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Callable_Impl<Ret (Class &, Param...), decltype(call)>>(call));
}
@ -134,22 +81,6 @@ namespace chaiscript
}
/// \brief Creates a new Proxy_Function object from a std::function object
/// \param[in] f std::function to expose to ChaiScript
///
/// \b Example:
/// \code
/// std::function<int (char, float, std::string)> f = get_some_function();
/// chaiscript::ChaiScript chai;
/// chai.add(fun(f), "some_function");
/// \endcode
///
/// \sa \ref adding_functions
template<typename T>
Proxy_Function fun(const std::function<T> &f)
{
return Proxy_Function(chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Proxy_Function_Impl<T>>(f));
}
/// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it

View File

@ -44,7 +44,6 @@
#include "../dispatchkit/exception_specification.hpp"
#include "chaiscript_parser.hpp"
#include "chaiscript_prelude.chai"
namespace chaiscript
{
@ -356,13 +355,14 @@ namespace chaiscript
add(t_lib);
}
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, std::ref(m_engine)), "dump_system");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, std::ref(m_engine)), "dump_object");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::is_type, std::ref(m_engine)), "is_type");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::type_name, std::ref(m_engine)), "type_name");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::function_exists, std::ref(m_engine)), "function_exists");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_function_objects, std::ref(m_engine)), "get_functions");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_scripting_objects, std::ref(m_engine)), "get_objects");
m_engine.add(fun([this](){ m_engine.dump_system(); }), "dump_system");
m_engine.add(fun([this](const Boxed_Value &t_bv){ m_engine.dump_object(t_bv); }), "dump_object");
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_type){ return m_engine.is_type(t_bv, t_type); }), "is_type");
m_engine.add(fun([this](const Boxed_Value &t_bv){ return m_engine.type_name(t_bv); }), "type_name");
m_engine.add(fun([this](const std::string &t_f){ return m_engine.function_exists(t_f); }), "function_exists");
m_engine.add(fun([this](){ return m_engine.get_function_objects(); }), "get_functions");
m_engine.add(fun([this](){ return m_engine.get_scripting_objects(); }), "get_objects");
m_engine.add(chaiscript::make_shared<dispatch::Proxy_Function_Base, dispatch::Dynamic_Proxy_Function>(
[this](const std::vector<Boxed_Value> &t_params) {
return m_engine.call_exists(t_params);
@ -375,10 +375,10 @@ namespace chaiscript
return t_fun(t_params, this->m_engine.conversions());
}), "call");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type_name, std::ref(m_engine)), "name");
m_engine.add(fun([this](const Type_Info &t_ti){ return m_engine.get_type_name(t_ti); }), "name");
m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::get_type, std::ref(m_engine)), "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([this](const std::string &t_type_name, bool t_throw){ return m_engine.get_type(t_type_name, t_throw); }), "type");
m_engine.add(fun([this](const std::string &t_type_name){ return m_engine.get_type(t_type_name, true); }), "type");
m_engine.add(fun(
[=](const Type_Info &t_from, const Type_Info &t_to, const std::function<Boxed_Value (const Boxed_Value &)> &t_func) {
@ -387,26 +387,23 @@ namespace chaiscript
), "add_type_conversion");
typedef std::string (ChaiScript::*load_mod_1)(const std::string&);
typedef void (ChaiScript::*load_mod_2)(const std::string&, const std::string&);
m_engine.add(fun(static_cast<load_mod_1>(&ChaiScript::load_module), this), "load_module");
m_engine.add(fun(static_cast<load_mod_2>(&ChaiScript::load_module), this), "load_module");
m_engine.add(fun([this](const std::string &t_module, const std::string &t_file){ return load_module(t_module, t_file); }), "load_module");
m_engine.add(fun([this](const std::string &t_module){ return load_module(t_module); }), "load_module");
m_engine.add(fun(&ChaiScript::use, this), "use");
m_engine.add(fun(&ChaiScript::internal_eval_file, this), "eval_file");
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval");
m_engine.add(fun([this](const std::string &t_file){ return use(t_file); }), "use");
m_engine.add(fun([this](const std::string &t_file){ return internal_eval_file(t_file); }), "eval_file");
m_engine.add(fun([this](const std::string &t_str){ return internal_eval(t_str); }), "eval");
m_engine.add(fun([this](const AST_NodePtr &t_ast){ return internal_eval_ast(t_ast); }), "eval");
m_engine.add(fun(&ChaiScript::version_major), "version_major");
m_engine.add(fun(&ChaiScript::version_minor), "version_minor");
m_engine.add(fun(&ChaiScript::version_patch), "version_patch");
m_engine.add(fun(&ChaiScript::version), "version");
m_engine.add(fun(&ChaiScript::add_global_const, this), "add_global_const");
m_engine.add(fun(&ChaiScript::add_global, this), "add_global");
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const");
m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global");
do_eval(ChaiScript_Prelude::chaiscript_prelude(), "standard prelude");
}

View File

@ -1418,36 +1418,40 @@ namespace chaiscript
std::shared_ptr<dispatch::Dynamic_Proxy_Function> guard;
if (guardnode) {
guard = std::make_shared<dispatch::Dynamic_Proxy_Function>
(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), guardnode,
t_param_names, std::placeholders::_1, std::map<std::string, Boxed_Value>()), static_cast<int>(numparams), guardnode);
([&t_ss, t_param_names, guardnode](const std::vector<Boxed_Value> &t_params) {
return chaiscript::eval::detail::eval_function(t_ss, guardnode, t_param_names, t_params, std::map<std::string, Boxed_Value>());
}, static_cast<int>(numparams), guardnode);
}
try {
const std::string & l_annotation = annotation?annotation->text:"";
const std::string & function_name = children[static_cast<size_t>(1 + class_offset)]->text;
auto node = children.back();
if (function_name == class_name) {
param_types.push_front(class_name, Type_Info());
t_ss.add(std::make_shared<dispatch::detail::Dynamic_Object_Constructor>(class_name, std::make_shared<dispatch::Dynamic_Proxy_Function>(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), children.back(), t_param_names, std::placeholders::_1, std::map<std::string, Boxed_Value>()),
static_cast<int>(numparams), children.back(), param_types, l_annotation, guard)),
t_ss.add(std::make_shared<dispatch::detail::Dynamic_Object_Constructor>(class_name,
std::make_shared<dispatch::Dynamic_Proxy_Function>(
[&t_ss, t_param_names, node](const std::vector<Boxed_Value> &t_params) {
return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map<std::string, Boxed_Value>());
},
static_cast<int>(numparams), node, param_types, l_annotation, guard)),
function_name);
} else {
// if the type is unknown, then this generates a function that looks up the type
// at runtime. Defining the type first before this is called is better
auto type = t_ss.get_type(class_name, false);
param_types.push_front(class_name, type);
t_ss.add(
std::make_shared<dispatch::detail::Dynamic_Object_Function>(class_name,
std::make_shared<dispatch::Dynamic_Proxy_Function>(std::bind(chaiscript::eval::detail::eval_function,
std::ref(t_ss), children.back(),
t_param_names, std::placeholders::_1, std::map<std::string, Boxed_Value>()), static_cast<int>(numparams), children.back(),
param_types, l_annotation, guard), type), function_name);
t_ss.add(std::make_shared<dispatch::detail::Dynamic_Object_Function>(class_name,
std::make_shared<dispatch::Dynamic_Proxy_Function>(
[&t_ss, t_param_names, node](const std::vector<Boxed_Value> &t_params) {
return chaiscript::eval::detail::eval_function(t_ss, node, t_param_names, t_params, std::map<std::string, Boxed_Value>());
},
static_cast<int>(numparams), node, param_types, l_annotation, guard), type),
function_name);
}
}
catch (const exception::reserved_word_error &e) {
@ -1473,15 +1477,14 @@ namespace chaiscript
std::string class_name = (itr != d.end())?std::string(boxed_cast<std::string>(itr->second)):this->children[0]->text;
try {
std::string attr_name = this->children[static_cast<size_t>(1 + class_offset)]->text;
t_ss.add(
std::make_shared<dispatch::detail::Dynamic_Object_Function>(
std::move(class_name),
fun(std::function<Boxed_Value (dispatch::Dynamic_Object &)>(
std::bind(static_cast<Boxed_Value &(dispatch::Dynamic_Object::*)(const std::string &)>(&dispatch::Dynamic_Object::get_attr),
std::placeholders::_1,
this->children[static_cast<size_t>(1 + class_offset)]->text
))
),
fun([attr_name](dispatch::Dynamic_Object &t_obj) {
return t_obj.get_attr(attr_name);
}),
true
), this->children[static_cast<size_t>(1 + class_offset)]->text);

View File

@ -7,8 +7,6 @@
#ifndef CHAISCRIPT_PARSER_HPP_
#define CHAISCRIPT_PARSER_HPP_
#include <cstdint>
#include <cstring>
#include <exception>
#include <iostream>
#include <memory>
@ -16,6 +14,8 @@
#include <string>
#include <vector>
#include <cctype>
#include <cstring>
#include "../dispatchkit/boxed_value.hpp"
#include "chaiscript_common.hpp"

View File

@ -37,8 +37,7 @@ TEST_CASE("C++11 Lambdas Can Be Registered")
// in an std::function or provide the signature
chaiscript::ChaiScript chai;
// provide the signature
chai.add(chaiscript::fun<std::string ()>([] { return "hello"; } ), "f1");
chai.add(chaiscript::fun([]()->std::string { return "hello"; } ), "f1");
// wrap
chai.add(chaiscript::fun(std::function<std::string ()>([] { return "world"; } )), "f2");