Improved C++0x rvalue reference implementation differentiating lvalue and rvalue references. The previous implementation treated rvalue references as lvalue references which leads to a number of different wrapping issues.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-matevz@12160 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
c3b48505e2
commit
d8cc75946b
13 changed files with 399 additions and 32 deletions
|
|
@ -68,6 +68,19 @@ static String *Swig_clocal(SwigType *t, const_String_or_char_ptr name, const_Str
|
|||
Delete(lstrname);
|
||||
}
|
||||
break;
|
||||
case T_RVALUE_REFERENCE:
|
||||
if (value) {
|
||||
String *lstrname = SwigType_lstr(t, name);
|
||||
String *lstr = SwigType_lstr(t, 0);
|
||||
Printf(decl, "%s = (%s) &%s_defrvalue", lstrname, lstr, name);
|
||||
Delete(lstrname);
|
||||
Delete(lstr);
|
||||
} else {
|
||||
String *lstrname = SwigType_lstr(t, name);
|
||||
Printf(decl, "%s = 0", lstrname);
|
||||
Delete(lstrname);
|
||||
}
|
||||
break;
|
||||
case T_VOID:
|
||||
break;
|
||||
case T_VARARGS:
|
||||
|
|
@ -229,6 +242,34 @@ int Swig_cargs(Wrapper *w, ParmList *p) {
|
|||
Delete(defname);
|
||||
Delete(defvalue);
|
||||
}
|
||||
} else if (tycode == T_RVALUE_REFERENCE) {
|
||||
if (pvalue) {
|
||||
SwigType *tvalue;
|
||||
String *defname, *defvalue, *rvalue, *qvalue;
|
||||
rvalue = SwigType_typedef_resolve_all(pvalue);
|
||||
qvalue = SwigType_typedef_qualified(rvalue);
|
||||
defname = NewStringf("%s_defrvalue", lname);
|
||||
tvalue = Copy(type);
|
||||
SwigType_del_rvalue_reference(tvalue);
|
||||
tycode = SwigType_type(tvalue);
|
||||
if (tycode != T_USER) {
|
||||
/* plain primitive type, we copy the the def value */
|
||||
String *lstr = SwigType_lstr(tvalue, defname);
|
||||
defvalue = NewStringf("%s = %s", lstr, qvalue);
|
||||
Delete(lstr);
|
||||
} else {
|
||||
/* user type, we copy the reference value */
|
||||
String *str = SwigType_str(type, defname);
|
||||
defvalue = NewStringf("%s = %s", str, qvalue);
|
||||
Delete(str);
|
||||
}
|
||||
Wrapper_add_localv(w, defname, defvalue, NIL);
|
||||
Delete(tvalue);
|
||||
Delete(rvalue);
|
||||
Delete(qvalue);
|
||||
Delete(defname);
|
||||
Delete(defvalue);
|
||||
}
|
||||
} else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING))) {
|
||||
pvalue = (String *) "0";
|
||||
}
|
||||
|
|
@ -269,6 +310,13 @@ String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or
|
|||
Delete(lstr);
|
||||
}
|
||||
break;
|
||||
case T_RVALUE_REFERENCE:
|
||||
{
|
||||
String *lstr = SwigType_lstr(t, 0);
|
||||
Printf(fcall, "%s = (%s) &", name, lstr);
|
||||
Delete(lstr);
|
||||
}
|
||||
break;
|
||||
case T_USER:
|
||||
Printf(fcall, "%s = ", name);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ char cvsroot_stype_c[] = "$Id$";
|
|||
*
|
||||
* 'p.' = Pointer (*)
|
||||
* 'r.' = Reference (&)
|
||||
* 'z.' = Rvalue reference (&&)
|
||||
* 'a(n).' = Array of size n [n]
|
||||
* 'f(..,..).' = Function with arguments (args)
|
||||
* 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
|
||||
|
|
@ -235,7 +236,7 @@ int SwigType_isconst(SwigType *t) {
|
|||
int SwigType_ismutable(SwigType *t) {
|
||||
int r;
|
||||
SwigType *qt = SwigType_typedef_resolve_all(t);
|
||||
if (SwigType_isreference(qt) || SwigType_isarray(qt)) {
|
||||
if (SwigType_isreference(qt) || SwigType_isrvalue_reference(qt) || SwigType_isarray(qt)) {
|
||||
Delete(SwigType_pop(qt));
|
||||
}
|
||||
r = SwigType_isconst(qt);
|
||||
|
|
@ -423,6 +424,16 @@ SwigType *SwigType_default(SwigType *t) {
|
|||
Delete(nr);
|
||||
#else
|
||||
def = NewString("r.SWIGTYPE");
|
||||
#endif
|
||||
} else if (SwigType_isrvalue_reference(r)) {
|
||||
#ifdef SWIG_NEW_TYPE_DEFAULT
|
||||
SwigType *nr = Copy(r);
|
||||
SwigType_del_rvalue_reference(nr);
|
||||
def = NewString("z.");
|
||||
SwigType_add_default(def, nr);
|
||||
Delete(nr);
|
||||
#else
|
||||
def = NewString("z.SWIGTYPE");
|
||||
#endif
|
||||
} else if (SwigType_isarray(r)) {
|
||||
if (strcmp(cr, "a().SWIGTYPE") == 0) {
|
||||
|
|
@ -597,6 +608,12 @@ String *SwigType_str(SwigType *s, const_String_or_char_ptr id) {
|
|||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
} else if (SwigType_isrvalue_reference(element)) {
|
||||
Insert(result, 0, "&&");
|
||||
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
|
||||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
} else if (SwigType_isarray(element)) {
|
||||
DOH *size;
|
||||
Append(result, "[");
|
||||
|
|
@ -661,7 +678,7 @@ SwigType *SwigType_ltype(SwigType *s) {
|
|||
SwigType *tt = Copy(tc);
|
||||
td = 0;
|
||||
while ((td = SwigType_typedef_resolve(tt))) {
|
||||
if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
|
||||
if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td) || SwigType_isrvalue_reference(td))) {
|
||||
/* We need to use the typedef type */
|
||||
Delete(tt);
|
||||
tt = td;
|
||||
|
|
@ -701,6 +718,13 @@ SwigType *SwigType_ltype(SwigType *s) {
|
|||
Append(result, "p.");
|
||||
}
|
||||
firstarray = 0;
|
||||
} else if (SwigType_isrvalue_reference(element)) {
|
||||
if (notypeconv) {
|
||||
Append(result, element);
|
||||
} else {
|
||||
Append(result, "p.");
|
||||
}
|
||||
firstarray = 0;
|
||||
} else if (SwigType_isarray(element) && firstarray) {
|
||||
if (notypeconv) {
|
||||
Append(result, element);
|
||||
|
|
@ -765,6 +789,7 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) {
|
|||
int clear = 1;
|
||||
int firstarray = 1;
|
||||
int isreference = 0;
|
||||
int isfunction = 0;
|
||||
int isarray = 0;
|
||||
|
||||
result = NewStringEmpty();
|
||||
|
|
@ -777,14 +802,14 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) {
|
|||
rs = s;
|
||||
}
|
||||
|
||||
if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs))) {
|
||||
if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs) || SwigType_isrvalue_reference(rs))) {
|
||||
td = 0;
|
||||
} else {
|
||||
td = SwigType_typedef_resolve(rs);
|
||||
}
|
||||
|
||||
if (td) {
|
||||
if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
|
||||
if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td) || SwigType_isrvalue_reference(td))) {
|
||||
elements = SwigType_split(td);
|
||||
} else {
|
||||
elements = SwigType_split(rs);
|
||||
|
|
@ -836,6 +861,14 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) {
|
|||
Append(result, ")");
|
||||
}
|
||||
isreference = 1;
|
||||
} else if (SwigType_isrvalue_reference(element)) {
|
||||
Insert(result, 0, "&&");
|
||||
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
|
||||
Insert(result, 0, "(");
|
||||
Append(result, ")");
|
||||
}
|
||||
isreference = 1;
|
||||
clear = 0;
|
||||
} else if (SwigType_isarray(element)) {
|
||||
DOH *size;
|
||||
if (firstarray && !isreference) {
|
||||
|
|
@ -865,6 +898,7 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) {
|
|||
}
|
||||
Append(result, ")");
|
||||
Delete(parms);
|
||||
isfunction = 1;
|
||||
} else {
|
||||
String *bs = SwigType_namestr(element);
|
||||
Insert(result, 0, " ");
|
||||
|
|
@ -880,10 +914,12 @@ String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) {
|
|||
cast = NewStringf("(%s)", result);
|
||||
}
|
||||
if (name) {
|
||||
if (isreference) {
|
||||
if (isarray)
|
||||
Clear(cast);
|
||||
Append(cast, "*");
|
||||
if (!isfunction) {
|
||||
if (isreference) {
|
||||
if (isarray)
|
||||
Clear(cast);
|
||||
Append(cast, "*");
|
||||
}
|
||||
}
|
||||
Append(cast, name);
|
||||
}
|
||||
|
|
@ -914,6 +950,12 @@ String *SwigType_lcaststr(SwigType *s, const_String_or_char_ptr name) {
|
|||
Delete(str);
|
||||
if (name)
|
||||
Append(result, name);
|
||||
} else if (SwigType_isrvalue_reference(s)) {
|
||||
String *str = SwigType_str(s, 0);
|
||||
Printf(result, "(%s)", str);
|
||||
Delete(str);
|
||||
if (name)
|
||||
Append(result, name);
|
||||
} else if (SwigType_isqualifier(s)) {
|
||||
String *lstr = SwigType_lstr(s, 0);
|
||||
Printf(result, "(%s)%s", lstr, name);
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ extern "C" {
|
|||
#define T_FUNCTION 37
|
||||
#define T_MPOINTER 38
|
||||
#define T_VARARGS 39
|
||||
#define T_RVALUE_REFERENCE 40
|
||||
#define T_SYMBOL 98
|
||||
#define T_ERROR 99
|
||||
|
||||
|
|
@ -123,6 +124,8 @@ extern "C" {
|
|||
extern SwigType *SwigType_pop_arrays(SwigType *t);
|
||||
extern SwigType *SwigType_add_reference(SwigType *t);
|
||||
extern SwigType *SwigType_del_reference(SwigType *t);
|
||||
extern SwigType *SwigType_add_rvalue_reference(SwigType *t);
|
||||
extern SwigType *SwigType_del_rvalue_reference(SwigType *t);
|
||||
extern SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual);
|
||||
extern SwigType *SwigType_del_qualifier(SwigType *t);
|
||||
extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
|
||||
|
|
@ -146,6 +149,7 @@ extern "C" {
|
|||
extern int SwigType_ismemberpointer(SwigType *t);
|
||||
extern int SwigType_isreference(SwigType *t);
|
||||
extern int SwigType_isreference_return(SwigType *t);
|
||||
extern int SwigType_isrvalue_reference(SwigType *t);
|
||||
extern int SwigType_isarray(SwigType *t);
|
||||
extern int SwigType_prefix_is_simple_1D_array(SwigType *t);
|
||||
extern int SwigType_isfunction(SwigType *t);
|
||||
|
|
|
|||
|
|
@ -942,13 +942,13 @@ int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *
|
|||
$*n_ltype
|
||||
*/
|
||||
|
||||
if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype))) {
|
||||
if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type))) {
|
||||
if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype)) || (SwigType_isrvalue_reference(ftype))) {
|
||||
if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type) || SwigType_isrvalue_reference(type))) {
|
||||
star_type = Copy(ftype);
|
||||
} else {
|
||||
star_type = Copy(type);
|
||||
}
|
||||
if (!SwigType_isreference(star_type)) {
|
||||
if (!(SwigType_isreference(star_type) || SwigType_isrvalue_reference(star_type))) {
|
||||
if (SwigType_isarray(star_type)) {
|
||||
SwigType_del_element(star_type);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ char cvsroot_typeobj_c[] = "$Id$";
|
|||
*
|
||||
* 'p.' = Pointer (*)
|
||||
* 'r.' = Reference (&)
|
||||
* 'z.' = Rvalue reference (&&)
|
||||
* 'a(n).' = Array of size n [n]
|
||||
* 'f(..,..).' = Function with arguments (args)
|
||||
* 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
|
||||
|
|
@ -75,6 +76,7 @@ char cvsroot_typeobj_c[] = "$Id$";
|
|||
*
|
||||
* SwigType_add_pointer()
|
||||
* SwigType_add_reference()
|
||||
* SwigType_add_rvalue_reference()
|
||||
* SwigType_add_array()
|
||||
*
|
||||
* These are used to build new types. There are also functions to undo these
|
||||
|
|
@ -82,12 +84,14 @@ char cvsroot_typeobj_c[] = "$Id$";
|
|||
*
|
||||
* SwigType_del_pointer()
|
||||
* SwigType_del_reference()
|
||||
* SwigType_del_rvalue_reference()
|
||||
* SwigType_del_array()
|
||||
*
|
||||
* In addition, there are query functions
|
||||
*
|
||||
* SwigType_ispointer()
|
||||
* SwigType_isreference()
|
||||
* SwigType_isrvalue_reference()
|
||||
* SwigType_isarray()
|
||||
*
|
||||
* Finally, there are some data extraction functions that can be used to
|
||||
|
|
@ -409,6 +413,41 @@ int SwigType_isreference(SwigType *t) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Rvalue References
|
||||
*
|
||||
* SwigType_add_rvalue_reference()
|
||||
* SwigType_del_rvalue_reference()
|
||||
* SwigType_isrvalue_reference()
|
||||
*
|
||||
* Add, remove, and test if a type is a rvalue reference. The deletion and query
|
||||
* functions take into account qualifiers (if any).
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
SwigType *SwigType_add_rvalue_reference(SwigType *t) {
|
||||
Insert(t, 0, "z.");
|
||||
return t;
|
||||
}
|
||||
|
||||
SwigType *SwigType_del_rvalue_reference(SwigType *t) {
|
||||
char *c = Char(t);
|
||||
int check = strncmp(c, "z.", 2);
|
||||
assert(check == 0);
|
||||
Delslice(t, 0, 2);
|
||||
return t;
|
||||
}
|
||||
|
||||
int SwigType_isrvalue_reference(SwigType *t) {
|
||||
char *c;
|
||||
if (!t)
|
||||
return 0;
|
||||
c = Char(t);
|
||||
if (strncmp(c, "z.", 2) == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Qualifiers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1206,6 +1206,8 @@ int SwigType_type(SwigType *t) {
|
|||
return T_ARRAY;
|
||||
if (strncmp(c, "r.", 2) == 0)
|
||||
return T_REFERENCE;
|
||||
if (strncmp(c, "z.", 2) == 0)
|
||||
return T_RVALUE_REFERENCE;
|
||||
if (strncmp(c, "m(", 2) == 0)
|
||||
return T_MPOINTER;
|
||||
if (strncmp(c, "q(", 2) == 0) {
|
||||
|
|
@ -1540,6 +1542,11 @@ void SwigType_remember_clientdata(SwigType *t, const_String_or_char_ptr clientda
|
|||
SwigType_del_reference(tt);
|
||||
SwigType_add_pointer(tt);
|
||||
SwigType_remember_clientdata(tt, clientdata);
|
||||
} else if (SwigType_isrvalue_reference(t)) {
|
||||
SwigType *tt = Copy(t);
|
||||
SwigType_del_rvalue_reference(tt);
|
||||
SwigType_add_pointer(tt);
|
||||
SwigType_remember_clientdata(tt, clientdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue