Enabled short hand for adding new methods to existing C++ types

This commit is contained in:
Jason Turner 2009-09-20 21:32:39 +00:00
parent 593c6c68ee
commit 160f64e9c2
2 changed files with 28 additions and 17 deletions

View File

@ -1,6 +1,8 @@
#ifndef __DYNAMIC_OBJECT_HPP__ #ifndef __DYNAMIC_OBJECT_HPP__
#define __DYNAMIC_OBJECT_HPP__ #define __DYNAMIC_OBJECT_HPP__
#include <boost/optional.hpp>
namespace chaiscript namespace chaiscript
{ {
class Dynamic_Object class Dynamic_Object
@ -43,21 +45,22 @@ namespace chaiscript
return t_do.get_attr(t_attr_name); return t_do.get_attr(t_attr_name);
} }
bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name) bool dynamic_object_typename_match(const std::vector<Boxed_Value> &bvs, const std::string &name,
{ const boost::optional<Type_Info> &ti)
try {
const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(bv);
return d.get_type_name() == name;
} catch (const std::bad_cast &) {
return false;
}
}
bool dynamic_object_typename_match(const std::vector<Boxed_Value> &bvs, const std::string &name)
{ {
if (bvs.size() > 0) if (bvs.size() > 0)
{ {
return dynamic_object_typename_match(bvs.front(), name); try {
const Dynamic_Object &d = boxed_cast<const Dynamic_Object &>(bvs[0]);
return d.get_type_name() == name;
} catch (const std::bad_cast &) {
if (ti)
{
return bvs[0].get_type_info().bare_equal(*ti);
} else {
return false;
}
}
} else { } else {
return false; return false;
} }
@ -73,9 +76,10 @@ namespace chaiscript
public: public:
Dynamic_Object_Function( Dynamic_Object_Function(
const std::string &t_type_name, const std::string &t_type_name,
const Proxy_Function &t_func) const Proxy_Function &t_func,
const boost::optional<Type_Info> &t_ti = boost::optional<Type_Info>())
: Proxy_Function_Base(t_func->get_param_types()), : Proxy_Function_Base(t_func->get_param_types()),
m_type_name(t_type_name), m_func(t_func) m_type_name(t_type_name), m_func(t_func), m_ti(t_ti)
{ {
assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0)
&& "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); && "Programming error, Dynamic_Object_Function must have at least one parameter (this)");
@ -96,7 +100,7 @@ namespace chaiscript
virtual bool call_match(const std::vector<Boxed_Value> &vals) const virtual bool call_match(const std::vector<Boxed_Value> &vals) const
{ {
if (dynamic_object_typename_match(vals, m_type_name)) if (dynamic_object_typename_match(vals, m_type_name, m_ti))
{ {
return m_func->call_match(vals); return m_func->call_match(vals);
} else { } else {
@ -106,7 +110,7 @@ namespace chaiscript
virtual Boxed_Value operator()(const std::vector<Boxed_Value> &params) const virtual Boxed_Value operator()(const std::vector<Boxed_Value> &params) const
{ {
if (dynamic_object_typename_match(params, m_type_name)) if (dynamic_object_typename_match(params, m_type_name, m_ti))
{ {
return (*m_func)(params); return (*m_func)(params);
} else { } else {
@ -127,6 +131,7 @@ namespace chaiscript
private: private:
std::string m_type_name; std::string m_type_name;
Proxy_Function m_func; Proxy_Function m_func;
boost::optional<Type_Info> m_ti;
}; };

View File

@ -960,11 +960,17 @@ namespace chaiscript
} }
else { else {
boost::optional<chaiscript::Type_Info> ti;
try {
ti = ss.get_type(class_name);
} catch (const std::range_error &) {
// No biggie, the type name is just not known
}
ss.add(Proxy_Function ss.add(Proxy_Function
(new Dynamic_Object_Function(class_name, Proxy_Function(new Dynamic_Proxy_Function(boost::bind(&eval_function<Eval_System>, (new Dynamic_Object_Function(class_name, Proxy_Function(new Dynamic_Proxy_Function(boost::bind(&eval_function<Eval_System>,
boost::ref(ss), node->children.back(), boost::ref(ss), node->children.back(),
param_names, _1), numparams, param_names, _1), numparams,
annotation, guard)))), function_name); annotation, guard)), ti)), function_name);
} }
} }