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:
William S Fulton 2013-12-12 07:59:47 +00:00
commit e95ac82651
5 changed files with 41 additions and 6 deletions

View file

@ -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; }
%}
/*

View 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);

View file

@ -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");
}

View file

@ -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");
}

View file

@ -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);