Add support for automatic conversion between chaiscript functions and boost::function. Might merit some look to see how much overhead this adds.
This commit is contained in:
@@ -118,6 +118,10 @@ IF(BUILD_TESTING)
|
|||||||
target_link_libraries(functor_creation_test ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB})
|
target_link_libraries(functor_creation_test ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB})
|
||||||
add_test(NAME Functor_Creation_Test COMMAND functor_creation_test)
|
add_test(NAME Functor_Creation_Test COMMAND functor_creation_test)
|
||||||
|
|
||||||
|
add_executable(functor_cast_test unittests/functor_cast_test.cpp)
|
||||||
|
target_link_libraries(functor_cast_test ${DYNAMIC_LOADER} ${Boost_LIBRARIES} ${READLINE_LIB})
|
||||||
|
add_test(NAME Functor_Cast_Test COMMAND functor_cast_test)
|
||||||
|
|
||||||
add_library(test_module MODULE src/test_module.cpp)
|
add_library(test_module MODULE src/test_module.cpp)
|
||||||
target_link_libraries(test_module ${Boost_LIBRARIES})
|
target_link_libraries(test_module ${Boost_LIBRARIES})
|
||||||
|
|
||||||
|
@@ -19,13 +19,13 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
// Cast_Helper helper classes
|
// Cast_Helper_Inner helper classes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic Cast_Helper, for casting to any type
|
* Generic Cast_Helper_Inner, for casting to any type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper
|
struct Cast_Helper_Inner
|
||||||
{
|
{
|
||||||
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
|
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
|
||||||
|
|
||||||
@@ -51,10 +51,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a const & type
|
* Cast_Helper_Inner for casting to a const & type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<const Result &>
|
struct Cast_Helper_Inner<const Result &>
|
||||||
{
|
{
|
||||||
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
|
typedef typename boost::reference_wrapper<typename boost::add_const<Result>::type > Result_Type;
|
||||||
|
|
||||||
@@ -80,10 +80,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a const * type
|
* Cast_Helper_Inner for casting to a const * type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<const Result *>
|
struct Cast_Helper_Inner<const Result *>
|
||||||
{
|
{
|
||||||
typedef const Result * Result_Type;
|
typedef const Result * Result_Type;
|
||||||
|
|
||||||
@@ -109,10 +109,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a * type
|
* Cast_Helper_Inner for casting to a * type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<Result *>
|
struct Cast_Helper_Inner<Result *>
|
||||||
{
|
{
|
||||||
typedef Result * Result_Type;
|
typedef Result * Result_Type;
|
||||||
|
|
||||||
@@ -128,10 +128,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a & type
|
* Cast_Helper_Inner for casting to a & type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<Result &>
|
struct Cast_Helper_Inner<Result &>
|
||||||
{
|
{
|
||||||
typedef typename boost::reference_wrapper<Result> Result_Type;
|
typedef typename boost::reference_wrapper<Result> Result_Type;
|
||||||
|
|
||||||
@@ -147,10 +147,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a boost::shared_ptr<> type
|
* Cast_Helper_Inner for casting to a boost::shared_ptr<> type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<typename boost::shared_ptr<Result> >
|
struct Cast_Helper_Inner<typename boost::shared_ptr<Result> >
|
||||||
{
|
{
|
||||||
typedef typename boost::shared_ptr<Result> Result_Type;
|
typedef typename boost::shared_ptr<Result> Result_Type;
|
||||||
|
|
||||||
@@ -161,10 +161,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a boost::shared_ptr<const> type
|
* Cast_Helper_Inner for casting to a boost::shared_ptr<const> type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<typename boost::shared_ptr<const Result> >
|
struct Cast_Helper_Inner<typename boost::shared_ptr<const Result> >
|
||||||
{
|
{
|
||||||
typedef typename boost::shared_ptr<const Result> Result_Type;
|
typedef typename boost::shared_ptr<const Result> Result_Type;
|
||||||
|
|
||||||
@@ -180,10 +180,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a const boost::shared_ptr<> & type
|
* Cast_Helper_Inner for casting to a const boost::shared_ptr<> & type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<const boost::shared_ptr<Result> &>
|
struct Cast_Helper_Inner<const boost::shared_ptr<Result> &>
|
||||||
{
|
{
|
||||||
typedef typename boost::shared_ptr<Result> Result_Type;
|
typedef typename boost::shared_ptr<Result> Result_Type;
|
||||||
|
|
||||||
@@ -194,10 +194,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a const boost::shared_ptr<const> & type
|
* Cast_Helper_Inner for casting to a const boost::shared_ptr<const> & type
|
||||||
*/
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<const boost::shared_ptr<const Result> &>
|
struct Cast_Helper_Inner<const boost::shared_ptr<const Result> &>
|
||||||
{
|
{
|
||||||
typedef typename boost::shared_ptr<const Result> Result_Type;
|
typedef typename boost::shared_ptr<const Result> Result_Type;
|
||||||
|
|
||||||
@@ -215,10 +215,10 @@ namespace chaiscript
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a Boxed_Value type
|
* Cast_Helper_Inner for casting to a Boxed_Value type
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Cast_Helper<Boxed_Value>
|
struct Cast_Helper_Inner<Boxed_Value>
|
||||||
{
|
{
|
||||||
typedef const Boxed_Value & Result_Type;
|
typedef const Boxed_Value & Result_Type;
|
||||||
|
|
||||||
@@ -229,10 +229,10 @@ namespace chaiscript
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cast_Helper for casting to a const Boxed_Value & type
|
* Cast_Helper_Inner for casting to a const Boxed_Value & type
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Cast_Helper<const Boxed_Value &>
|
struct Cast_Helper_Inner<const Boxed_Value &>
|
||||||
{
|
{
|
||||||
typedef const Boxed_Value & Result_Type;
|
typedef const Boxed_Value & Result_Type;
|
||||||
|
|
||||||
@@ -241,12 +241,22 @@ namespace chaiscript
|
|||||||
return ob;
|
return ob;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exposed Cast_Helper object that by default just calls the Cast_Helper_Inner
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
struct Cast_Helper
|
||||||
|
{
|
||||||
|
typedef typename Cast_Helper_Inner<T>::Result_Type Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
return Cast_Helper_Inner<T>::cast(ob);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -251,8 +251,21 @@ namespace chaiscript
|
|||||||
return Boxed_POD_Value(ob);
|
return Boxed_POD_Value(ob);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for converting from Boxed_Value to Boxed_POD_Value
|
||||||
|
*/
|
||||||
|
template<>
|
||||||
|
struct Cast_Helper<const Boxed_POD_Value>
|
||||||
|
{
|
||||||
|
typedef Boxed_POD_Value Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
return Boxed_POD_Value(ob);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,9 @@
|
|||||||
#include "proxy_functions.hpp"
|
#include "proxy_functions.hpp"
|
||||||
#include "function_call_detail.hpp"
|
#include "function_call_detail.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +69,65 @@ namespace chaiscript
|
|||||||
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv));
|
return functor<FunctionType>(boxed_cast<Const_Proxy_Function >(bv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail{
|
||||||
|
/**
|
||||||
|
* Cast helper to handle automatic casting to const boost::function &
|
||||||
|
*/
|
||||||
|
template<typename Signature>
|
||||||
|
struct Cast_Helper<const boost::function<Signature> &>
|
||||||
|
{
|
||||||
|
typedef boost::function<Signature> Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
|
{
|
||||||
|
return functor<Signature>(ob);
|
||||||
|
} else {
|
||||||
|
return Cast_Helper_Inner<const boost::function<Signature> &>::cast(ob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast helper to handle automatic casting to boost::function
|
||||||
|
*/
|
||||||
|
template<typename Signature>
|
||||||
|
struct Cast_Helper<boost::function<Signature> >
|
||||||
|
{
|
||||||
|
typedef boost::function<Signature> Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
|
{
|
||||||
|
return functor<Signature>(ob);
|
||||||
|
} else {
|
||||||
|
return Cast_Helper_Inner<boost::function<Signature> >::cast(ob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast helper to handle automatic casting to const boost::function
|
||||||
|
*/
|
||||||
|
template<typename Signature>
|
||||||
|
struct Cast_Helper<const boost::function<Signature> >
|
||||||
|
{
|
||||||
|
typedef boost::function<Signature> Result_Type;
|
||||||
|
|
||||||
|
static Result_Type cast(const Boxed_Value &ob)
|
||||||
|
{
|
||||||
|
if (ob.get_type_info().bare_equal(user_type<Const_Proxy_Function>()))
|
||||||
|
{
|
||||||
|
return functor<Signature>(ob);
|
||||||
|
} else {
|
||||||
|
return Cast_Helper_Inner<const boost::function<Signature> >::cast(ob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -119,6 +119,7 @@ namespace chaiscript
|
|||||||
&& (ti.bare_equal(user_type<Boxed_POD_Value>())
|
&& (ti.bare_equal(user_type<Boxed_POD_Value>())
|
||||||
|| ti.bare_equal(bv.get_type_info())
|
|| ti.bare_equal(bv.get_type_info())
|
||||||
|| dynamic_cast_converts(ti, bv.get_type_info())
|
|| dynamic_cast_converts(ti, bv.get_type_info())
|
||||||
|
|| bv.get_type_info().bare_equal(user_type<boost::shared_ptr<const Proxy_Function_Base> >())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
25
unittests/functor_cast_test.cpp
Normal file
25
unittests/functor_cast_test.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include <chaiscript/utility/utility.hpp>
|
||||||
|
|
||||||
|
double test_call(const boost::function<double (int)> &f, int val)
|
||||||
|
{
|
||||||
|
return f(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
chaiscript::ChaiScript chai;
|
||||||
|
|
||||||
|
chai.add(chaiscript::fun(&test_call), "test_call");
|
||||||
|
|
||||||
|
chai.eval("def func(i) { return i * 3.5; };");
|
||||||
|
double d = chai.eval<double>("test_call(func, 3)");
|
||||||
|
|
||||||
|
if (d == 3 * 3.5)
|
||||||
|
{
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
} else {
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user