From b0ea5581c3ccfabcfe74fcc1aaad118a136c6bdc Mon Sep 17 00:00:00 2001 From: Xavier Delacour Date: Mon, 26 Mar 2012 15:45:02 +0000 Subject: [PATCH] add extra logic to the octave_swig_type::dims(void) method: it checks if the user has defined a __dims__ method and uses this in stead of returning (1,1) (patch from jgillis, sf 3425993) git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12955 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/octave/Makefile.in | 3 +- Examples/test-suite/octave/octave_dim_runme.m | 18 ++ Examples/test-suite/octave_dim.i | 160 ++++++++++++++++++ Lib/octave/octrun.swg | 52 +++++- 4 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 Examples/test-suite/octave/octave_dim_runme.m create mode 100644 Examples/test-suite/octave_dim.i diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in index c49ce2624..88f533fd1 100644 --- a/Examples/test-suite/octave/Makefile.in +++ b/Examples/test-suite/octave/Makefile.in @@ -12,7 +12,8 @@ top_builddir = @top_builddir@ CPP_TEST_CASES += \ li_std_pair_extra \ li_std_string_extra \ - octave_cell_deref + octave_cell_deref\ + octave_dim CPP_TEST_BROKEN += \ implicittest \ diff --git a/Examples/test-suite/octave/octave_dim_runme.m b/Examples/test-suite/octave/octave_dim_runme.m new file mode 100644 index 000000000..9bb7f2b1c --- /dev/null +++ b/Examples/test-suite/octave/octave_dim_runme.m @@ -0,0 +1,18 @@ +octave_dim + +assert(all(size(Foo45a())==[4 5])); +assert(all(size(Foo456a())==[4 5 6])); +assert(all(size(Foo4a())==[4 1])); +assert(all(size(Foo4b())==[4 1])); +assert(all(size(Foo())==[1 1])); +assert(all(size(Bar1())==[1 1])); +assert(all(size(Bar2())==[1 1])); +assert(all(size(Baz1())==[3 4])); +assert(all(size(Baz2())==[3 4])); +assert(all(size(Baz3())==[3 4])); +assert(all(size(Baz4())==[3 4])); + +% Assertions will not work, but kept for future reference. +%assert(all(size(Baz5())==[3 4])); +%assert(all(size(Baz6())==[3 4])); +%assert(all(size(Baz7())==[3 4])); diff --git a/Examples/test-suite/octave_dim.i b/Examples/test-suite/octave_dim.i new file mode 100644 index 000000000..c74285808 --- /dev/null +++ b/Examples/test-suite/octave_dim.i @@ -0,0 +1,160 @@ +%module octave_dim + +%include "std_vector.i" + +namespace std { + %template(IntVector) vector; +} + + +%typemap(out) Matrix { + $result = $1; +} + +// Code below will not work. Kept for future reference. +// Reason: there is no octave_value(Array) constructor +//%typemap(out) Array { +// $result = octave_value($1,true); +//} + + +%inline %{ + +class Foo45a { +public: + std::vector __dims__() const { + std::vector ret(2); + ret[0] = 4; + ret[1] = 5; + return ret; + } +}; + +// doubles are not converted to ints. +class Bar1 { +public: + std::vector __dims__() const { + std::vector ret(2); + ret[0] = 4; + ret[1] = 5; + return ret; + } +}; + +class Bar2 { +public: + std::string __dims__() const { + return "foo"; + } +}; + + +class Foo4a { +public: + std::vector __dims__() const { + std::vector ret(1); + ret[0] = 4; + return ret; + } +}; + +class Foo4b { +public: + int __dims__() const { + return 4; + } +}; + +class Foo456a { +public: + std::vector __dims__() const { + std::vector ret(3); + ret[0] = 4; + ret[1] = 5; + ret[2] = 6; + return ret; + } +}; + + + + +class Foo { + +}; + + +class Baz1 { +public: + Cell __dims__() const { + Cell c(1,2); + c(0) = 3; + c(1) = 4; + return c; + } +}; + +class Baz2 { +public: + Cell __dims__() const { + Cell c(2,1); + c(0) = 3; + c(1) = 4; + return c; + } +}; + +class Baz3 { +public: + Matrix __dims__() const { + Matrix c(2,1); + c(0) = 3; + c(1) = 4; + return c; + } +}; + +class Baz4 { +public: + Matrix __dims__() const { + Matrix c(1,2); + c(0) = 3; + c(1) = 4; + return c; + } +}; + +class Baz5 { +public: + Array __dims__() const { + Array c(2,1); + c(0) = 3; + c(1) = 4; + return c; + } +}; + +class Baz6 { +public: + Array __dims__() const { + Array c(1,2); + c(0) = 3; + c(1) = 4; + return c; + } +}; + +// Code below will not work. Kept for future reference. +// Reason: there is no octave_value(dim_vector) constructor +// class Baz7 { +//public: +// dim_vector __dims__() const { +// octave_value v = dim_vector(3,4); +// Array a = v.int_vector_value(); +// if (error_state) return dim_vector(1,1); +// int mysize = a.numel(); +// return dim_vector(3,4); +// } +//}; + +%} diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg index 194946276..5f1c18af4 100644 --- a/Lib/octave/octrun.swg +++ b/Lib/octave/octrun.swg @@ -400,7 +400,57 @@ namespace Swig { } dim_vector dims(void) const { - return dim_vector(1,1); + octave_swig_type *nc_this = const_cast < octave_swig_type *>(this); + + // Find the __dims__ method of this object + member_value_pair *m = nc_this->find_member("__dims__", false); + + if (!m) return dim_vector(1,1); + + // Call the __dims__ method of this object + octave_value_list inarg; + inarg.append(nc_this->as_value()); + octave_value_list outarg = nc_this->member_invoke(m, inarg, 1); + + // __dims__ should return (at least) one output argument + if (outarg.length() < 1) return dim_vector(1,1); + + octave_value & out = outarg(0); + + // Return value should be cell or matrix of integers + if (out.is_cell()) { + const Cell & c=out.cell_value(); + int ndim = c.rows(); + if (ndim==1 && c.columns()!=1) ndim = c.columns(); + + dim_vector d; + d.resize(ndim); + + // Fill in dim_vector + for (int k=0;k a = out.int_vector_value(); + if (error_state) return dim_vector(1,1); + dim_vector d; + d.resize(a.numel()); + for (int k=0;k