diff options
author | Karl Wette <karl.wette@ligo.org> | 2018-05-12 02:29:07 +1000 |
---|---|---|
committer | Karl Wette <karl.wette@ligo.org> | 2018-05-12 22:25:07 +1000 |
commit | d0b1105f3018516e4a94dd57e6bae83167bf2f1c (patch) | |
tree | b904e0487ebd92af5a5b9c7821e23efeac3aff51 | |
parent | 94e8853e610cf545ba42bfa77d8ac1d659adb7a5 (diff) | |
download | swig-d0b1105f3018516e4a94dd57e6bae83167bf2f1c.tar.gz |
Lib/octave: use new class for function member dereference with Octave >= 4.4
-rw-r--r-- | Lib/octave/octrun.swg | 80 | ||||
-rw-r--r-- | Lib/octave/octruntime.swg | 30 |
2 files changed, 106 insertions, 4 deletions
diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg index ae014f9bd..45105e207 100644 --- a/Lib/octave/octrun.swg +++ b/Lib/octave/octrun.swg @@ -151,6 +151,67 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); const swig_type_info **base; }; +#if SWIG_OCTAVE_PREREQ(4,4,0) + // in Octave 4.4 behaviour of octave_builtin() appears to have changed and 'self' argument is no longer passed + // to function (maybe because this is now a 'method'??) so need to create our own octave_function subclass +#define SWIG_OCTAVE_BOUND_FUNC(func, args) octave_value(new octave_swig_bound_func(func, args)) + class octave_swig_bound_func : public octave_function { + public: + + octave_swig_bound_func(void) : octave_function(), method(0), first_args() + { } + + octave_swig_bound_func(octave_function* _method, octave_value_list _first_args) + : octave_function("", ""), method(_method), first_args(_first_args) + { } + + octave_swig_bound_func(const octave_swig_bound_func& f) = delete; + + octave_swig_bound_func& operator= (const octave_swig_bound_func& f) = delete; + + ~octave_swig_bound_func(void) = default; + + bool is_function(void) const { return true; } + + octave_function* function_value(bool = false) { return this; } + + octave_value_list call(octave::tree_evaluator& tw, int nargout = 0, const octave_value_list& args = octave_value_list()) { + octave_value_list all_args; + all_args.append(first_args); + all_args.append(args); + return method->call(tw, nargout, all_args); + } + + octave_value subsref(const std::string &ops, const std::list < octave_value_list > &idx) { + octave_value_list ovl = subsref(ops, idx, 1); + return ovl.length() ? ovl(0) : octave_value(); + } + + octave_value_list subsref(const std::string &ops, const std::list < octave_value_list > &idx, int nargout) { + assert(ops.size() > 0); + assert(ops.size() == idx.size()); + if (ops != "(") + error("invalid function call"); + octave::tree_evaluator& tw = octave::interpreter::the_interpreter()->get_evaluator(); + return call(tw, nargout, *idx.begin()); + } + + protected: + + octave_function* method; + octave_value_list first_args; + + std::set<std::string> dispatch_classes; + + private: + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA + }; + DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_swig_bound_func, "octave_swig_bound_func", "octave_swig_bound_func"); +#else +#define SWIG_OCTAVE_BOUND_FUNC(func, args) octave_value(func) +#endif + // octave_swig_type plays the role of both the shadow class and the class // representation within Octave, since there is no support for classes. // @@ -323,13 +384,17 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); } octave_value_list member_deref(member_value_pair *m, const octave_value_list &args) { - if (m->second.is_defined()) - return m->second; - else if (m->first) { + if (m->second.is_defined()) { + if (m->second.is_function() || m->second.is_function_handle()) { + return SWIG_OCTAVE_BOUND_FUNC(m->second.function_value(), args); + } else { + return m->second; + } + } else if (m->first) { if (m->first->get_method) return m->first->get_method(args, 1); else if (m->first->method) - return octave_value(new octave_builtin(m->first->method)); + return SWIG_OCTAVE_BOUND_FUNC(new octave_builtin(m->first->method), args); } error("undefined member"); return octave_value_list(); @@ -860,7 +925,14 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); octave_function *fcn = is_valid_function(symbol, std::string(), false); if (!fcn) return false; +#if SWIG_OCTAVE_PREREQ(4,4,0) + octave::tree_evaluator& tw = octave::interpreter::the_interpreter()->get_evaluator(); + octave_value_list retval = fcn->call(tw, 1, args); + if (retval.length() == 1) + ret = retval(0); +#else ret = fcn->do_multi_index_op(1, args)(0); +#endif return true; } diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg index 46faade9c..f98bf4fe4 100644 --- a/Lib/octave/octruntime.swg +++ b/Lib/octave/octruntime.swg @@ -370,8 +370,38 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) { #endif #endif +#if SWIG_OCTAVE_PREREQ(4,4,0) + { + octave::type_info& typeinfo = octave::interpreter::the_interpreter()->get_type_info(); + string_vector types = typeinfo.installed_type_names(); + bool register_octave_swig_ref = true; + bool register_octave_swig_packed = true; + bool register_octave_swig_bound_func = true; + for (int i = 0; i < types.numel(); ++i) { + if (types(i) == octave_swig_ref::static_type_name()) { + register_octave_swig_ref = false; + } + if (types(i) == octave_swig_packed::static_type_name()) { + register_octave_swig_packed = false; + } + if (types(i) == octave_swig_bound_func::static_type_name()) { + register_octave_swig_bound_func = false; + } + } + if (register_octave_swig_ref) { + octave_swig_ref::register_type(); + } + if (register_octave_swig_packed) { + octave_swig_packed::register_type(); + } + if (register_octave_swig_bound_func) { + octave_swig_bound_func::register_type(); + } + } +#else octave_swig_ref::register_type(); octave_swig_packed::register_type(); +#endif SWIG_InitializeModule(0); SWIG_PropagateClientData(); |