Nested C class setters restored in c++out mode for Octave
Suitable casts are required so that assignment of instances of nested classes
work as the nested class is duplicated in the global namespace, eg:
struct Outer {
struct Nested {
int bar;
} bar_instance;
};
Outer.bar_instance can now be assigned to.
This commit is contained in:
parent
cf3696e8f9
commit
e95ac82651
5 changed files with 41 additions and 6 deletions
|
|
@ -23,6 +23,8 @@ void setValues(struct Outer *outer, int val) {
|
|||
outer->inside3 = &outer->inside2;
|
||||
outer->inside4[0].val = val * 4;
|
||||
}
|
||||
|
||||
int getInside1Val(struct Outer *n) { return n->inside1.val; }
|
||||
%}
|
||||
|
||||
/*
|
||||
|
|
|
|||
14
Examples/test-suite/octave/nested_structs_runme.m
Normal file
14
Examples/test-suite/octave/nested_structs_runme.m
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
nested_structs
|
||||
|
||||
named = nested_structs.Named();
|
||||
named.val = 999;
|
||||
assert(nested_structs.nestedByVal(named), 999);
|
||||
assert(nested_structs.nestedByPtr(named), 999);
|
||||
|
||||
outer = nested_structs.Outer();
|
||||
outer.inside1.val = 456;
|
||||
assert(nested_structs.getInside1Val(outer), 456);
|
||||
|
||||
outer.inside1 = named;
|
||||
assert(nested_structs.getInside1Val(outer), 999);
|
||||
|
||||
|
|
@ -159,7 +159,7 @@
|
|||
%typemap(memberin) SWIGTYPE [ANY] {
|
||||
if ($input) {
|
||||
size_t ii = 0;
|
||||
for (; ii < (size_t)$1_dim0; ++ii) $1[ii] = $input[ii];
|
||||
for (; ii < (size_t)$1_dim0; ++ii) *($1_ltype)&$1[ii] = ($*1_ltype)$input[ii];
|
||||
} else {
|
||||
%variable_nullref("$type","$name");
|
||||
}
|
||||
|
|
@ -168,7 +168,7 @@
|
|||
%typemap(globalin) SWIGTYPE [ANY] {
|
||||
if ($input) {
|
||||
size_t ii = 0;
|
||||
for (; ii < (size_t)$1_dim0; ++ii) $1[ii] = $input[ii];
|
||||
for (; ii < (size_t)$1_dim0; ++ii) *($1_ltype)&$1[ii] = ($*1_ltype)$input[ii];
|
||||
} else {
|
||||
%variable_nullref("$type","$name");
|
||||
}
|
||||
|
|
@ -181,7 +181,7 @@
|
|||
%variable_fail(res, "$type", "$name");
|
||||
} else if (inp) {
|
||||
size_t ii = 0;
|
||||
for (; ii < (size_t)$1_dim0; ++ii) $1[ii] = inp[ii];
|
||||
for (; ii < (size_t)$1_dim0; ++ii) *($1_ltype)&$1[ii] = ($*1_ltype)inp[ii];
|
||||
} else {
|
||||
%variable_nullref("$type", "$name");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3513,7 +3513,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
|
|||
while (p) {
|
||||
Setattr(p, "storage", $1);
|
||||
Setattr(p, "type" ,ty);
|
||||
if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name") || CPlusPlusOut)) {
|
||||
if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name"))) {
|
||||
SetFlag(p, "hasconsttype");
|
||||
SetFlag(p, "feature:immutable");
|
||||
}
|
||||
|
|
@ -3674,7 +3674,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
|
|||
while (n) {
|
||||
Setattr(n,"storage",$1);
|
||||
Setattr(n, "type", ty);
|
||||
if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name") || CPlusPlusOut)) {
|
||||
if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name"))) {
|
||||
SetFlag(n,"hasconsttype");
|
||||
SetFlag(n,"feature:immutable");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "swig.h"
|
||||
|
||||
extern int cparse_cplusplus;
|
||||
extern int CPlusPlusOut;
|
||||
static const char *cresult_variable_name = "result";
|
||||
|
||||
static Parm *nonvoid_parms(Parm *p) {
|
||||
|
|
@ -775,7 +776,25 @@ String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, Stri
|
|||
if (SwigType_type(type) != T_ARRAY) {
|
||||
if (!Strstr(type, "enum $unnamed")) {
|
||||
String *dref = Swig_wrapped_var_deref(type, pname1, varcref);
|
||||
Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
|
||||
int extra_cast = 0;
|
||||
if (CPlusPlusOut) {
|
||||
/* Required for C nested structs compiled as C++ as a duplicate of the nested struct is put into the global namespace.
|
||||
* We could improve this by adding the extra casts just for nested structs rather than all structs. */
|
||||
String *base = SwigType_base(type);
|
||||
extra_cast = SwigType_isclass(base);
|
||||
Delete(base);
|
||||
}
|
||||
if (extra_cast) {
|
||||
String *lstr;
|
||||
SwigType *ptype = Copy(type);
|
||||
SwigType_add_pointer(ptype);
|
||||
lstr = SwigType_lstr(ptype, 0);
|
||||
Printf(func, "if (%s) *(%s)&%s%s = %s", pname0, lstr, self, name, dref);
|
||||
Delete(lstr);
|
||||
Delete(ptype);
|
||||
} else {
|
||||
Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
|
||||
}
|
||||
Delete(dref);
|
||||
} else {
|
||||
Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue