Added support for const attribute access
This commit is contained in:
@@ -92,6 +92,7 @@ namespace chaiscript
|
|||||||
|
|
||||||
const Type_Info &ti = types[1];
|
const Type_Info &ti = types[1];
|
||||||
|
|
||||||
|
|
||||||
if (ti.is_undef() || vals[0].get_type_info().is_undef()
|
if (ti.is_undef() || vals[0].get_type_info().is_undef()
|
||||||
|| ti.bare_equal(user_type<Boxed_Value>())
|
|| ti.bare_equal(user_type<Boxed_Value>())
|
||||||
|| ti.bare_equal(user_type<Boxed_POD_Value>())
|
|| ti.bare_equal(user_type<Boxed_POD_Value>())
|
||||||
@@ -407,6 +408,81 @@ namespace chaiscript
|
|||||||
Func *m_dummy_func;
|
Func *m_dummy_func;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute getter Proxy_Function implementation
|
||||||
|
*/
|
||||||
|
template<typename T, typename Class>
|
||||||
|
class Attribute_Access : public Proxy_Function_Base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Attribute_Access(T Class::* t_attr)
|
||||||
|
: Proxy_Function_Base(param_types()),
|
||||||
|
m_attr(t_attr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Attribute_Access() {}
|
||||||
|
|
||||||
|
virtual bool operator==(const Proxy_Function_Base &t_func) const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const Attribute_Access<T, Class> &aa
|
||||||
|
= dynamic_cast<const Attribute_Access<T, Class> &>(t_func);
|
||||||
|
return m_attr == aa.m_attr;
|
||||||
|
} catch (const std::bad_cast &) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||||
|
{
|
||||||
|
if (params.size() == 1)
|
||||||
|
{
|
||||||
|
const Boxed_Value &bv = params[0];
|
||||||
|
if (bv.is_const())
|
||||||
|
{
|
||||||
|
const Class *o = boxed_cast<const Class *>(bv);
|
||||||
|
return Boxed_Value( boost::ref(o->*m_attr) );
|
||||||
|
} else {
|
||||||
|
Class *o = boxed_cast<Class *>(bv);
|
||||||
|
return Boxed_Value( boost::ref(o->*m_attr) );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw arity_error(params.size(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int get_arity() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool call_match(const std::vector<Boxed_Value> &vals) const
|
||||||
|
{
|
||||||
|
if (vals.size() != 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vals[0].get_type_info().bare_equal(user_type<Class>());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string annotation() const
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::vector<Type_Info> param_types()
|
||||||
|
{
|
||||||
|
std::vector<Type_Info> v;
|
||||||
|
v.push_back(user_type<T>());
|
||||||
|
v.push_back(user_type<Class>());
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
T Class::* m_attr;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown in the case that a multi method dispatch fails
|
* Exception thrown in the case that a multi method dispatch fails
|
||||||
* because no matching function was found
|
* because no matching function was found
|
||||||
|
@@ -13,74 +13,61 @@
|
|||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/function_types/components.hpp>
|
#include <boost/function_types/components.hpp>
|
||||||
#include <boost/function_types/function_type.hpp>
|
#include <boost/function_types/function_type.hpp>
|
||||||
|
#include <boost/function_types/is_member_object_pointer.hpp>
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/**
|
template<bool Object>
|
||||||
* Helper function for register_member function
|
struct Fun_Helper
|
||||||
*/
|
|
||||||
template<typename T, typename Class>
|
|
||||||
T &get_member(T Class::* m, Class *obj)
|
|
||||||
{
|
{
|
||||||
return (obj->*m);
|
template<typename T>
|
||||||
}
|
static Proxy_Function go(T t)
|
||||||
|
{
|
||||||
|
return Proxy_Function(
|
||||||
|
new Proxy_Function_Impl<
|
||||||
|
typename boost::function_types::function_type<boost::function_types::components<T> >::type> (
|
||||||
|
boost::function<
|
||||||
|
typename boost::function_types::function_type<boost::function_types::components<T> >::type
|
||||||
|
>(t)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<>
|
||||||
boost::function<T> mk_boost_fun(const boost::function<T> &f)
|
struct Fun_Helper<true>
|
||||||
{
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
boost::function<
|
|
||||||
typename boost::function_types::function_type<boost::function_types::components<T> >::type
|
|
||||||
> mk_boost_fun(T t)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
boost::function<
|
|
||||||
typename boost::function_types::function_type<boost::function_types::components<T> >::type
|
|
||||||
>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename Class>
|
|
||||||
Proxy_Function fun_helper(T Class::* m)
|
|
||||||
{
|
{
|
||||||
return fun_helper(boost::function<T& (Class *)>(boost::bind(&detail::get_member<T, Class>, m, _1)));
|
template<typename T, typename Class>
|
||||||
}
|
static Proxy_Function go(T Class::* m)
|
||||||
|
{
|
||||||
|
return Proxy_Function(new Attribute_Access<T, Class>(m));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Proxy_Function fun_helper(const boost::function<T> &f)
|
|
||||||
{
|
|
||||||
return Proxy_Function(new Proxy_Function_Impl<T>(f));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Proxy_Function fun(const boost::function<T> &f)
|
Proxy_Function fun(const boost::function<T> &f)
|
||||||
{
|
{
|
||||||
return detail::fun_helper(f);
|
return Proxy_Function(new Proxy_Function_Impl<T>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Proxy_Function fun(T t)
|
Proxy_Function fun(T t)
|
||||||
{
|
{
|
||||||
return detail::fun_helper(detail::mk_boost_fun(t));
|
return detail::Fun_Helper<boost::function_types::is_member_object_pointer<T>::value>::go(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename Q>
|
template<typename T, typename Q>
|
||||||
Proxy_Function fun(T t, const Q &q)
|
Proxy_Function fun(T t, const Q &q)
|
||||||
{
|
{
|
||||||
return detail::fun_helper(bind_first(t, q));
|
return fun(bind_first(t, q));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Q, typename R>
|
template<typename T, typename Q, typename R>
|
||||||
Proxy_Function fun(T t, const Q &q, const R &r)
|
Proxy_Function fun(T t, const Q &q, const R &r)
|
||||||
{
|
{
|
||||||
return detail::fun_helper(bind_first(bind_first(t, q), r));
|
return fun(bind_first(bind_first(t, q), r));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user