diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 992406535..443cf2256 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -409,6 +409,7 @@ CPP0X_TEST_CASES = \ cpp0x_function_objects \ cpp0x_strongly_typed_enumerations \ cpp0x_rvalue_reference \ + cpp0x_rvalue_reference2 \ cpp0x_variadic_templates \ cpp0x_alternate_function_syntax \ cpp0x_userdefined_literals \ diff --git a/Examples/test-suite/cpp0x_rvalue_reference.i b/Examples/test-suite/cpp0x_rvalue_reference.i index 5821c5ccf..67686bc0f 100644 --- a/Examples/test-suite/cpp0x_rvalue_reference.i +++ b/Examples/test-suite/cpp0x_rvalue_reference.i @@ -3,12 +3,13 @@ %module cpp0x_rvalue_reference %inline %{ +#include class A { public: int getAcopy() { return _a; } int *getAptr() { return &_a; } int &getAref() { return _a; } - int &&getAmove() { return _a; } + int &&getAmove() { return std::move(_a); } void setAcopy(int a) { _a = a; } void setAptr(int *a) { _a = *a; } diff --git a/Examples/test-suite/cpp0x_rvalue_reference2.i b/Examples/test-suite/cpp0x_rvalue_reference2.i new file mode 100644 index 000000000..a3e9d1784 --- /dev/null +++ b/Examples/test-suite/cpp0x_rvalue_reference2.i @@ -0,0 +1,83 @@ +%module cpp0x_rvalue_reference2 + +// This testcase tests lots of different places that rvalue reference syntax can be used + +%typemap(in) Something && "/*in Something && typemap*/" +%rename(OperatorRValue) Thingy::operator int&&; +%rename(memberFnRenamed) memberFn(short &&i); +%feature("compactdefaultargs") Thingy::compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef); +%feature("exception") Thingy::privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue); +%ignore Thingy::operator=; + +%inline %{ +#include +struct UserDef { + int a; +}; +static const bool PublicGlobalTrue = true; +static const UserDef PublicUserDef = UserDef(); +struct Thingy { + typedef int Integer; + int val; + int &lvalref; + int &&rvalref; + Thingy(int v) : val(v), lvalref(val), rvalref(22) {} + void refIn(long &i) {} + void rvalueIn(long &&i) {} + short && rvalueInOut(short &&i) { return std::move(i); } + static short && staticRvalueInOut(short &&i) { return std::move(i); } + // test both primitive and user defined rvalue reference default arguments and compactdefaultargs + void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef) {} + void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {} + operator int &&() {} + Thingy& operator=(const Thingy& rhs) { + val = rhs.val; + lvalref = rhs.lvalref; + rvalref = rhs.rvalref; + } +private: + static const bool PrivateTrue = true; + Thingy(); +}; + +short && globalRvalueInOut(short &&i) { return std::move(i); } + +Thingy &&globalrrval = Thingy(55); + +short && func(short &&i) { return std::move(i); } +Thingy getit() { return Thingy(22); } + +void rvalrefFunction1(int &&v = (int &&)5) {} +void rvalrefFunctionBYVAL(short (Thingy::*memFunc)(short)) {} +void rvalrefFunctionLVALUE(short &(Thingy::*memFunc)(short &)) {} +void rvalrefFunction2(short && (Thingy::*memFunc)(short &&)) {} +void rvalrefFunction3(short && (*memFunc)(short &&)) {} + +template struct RemoveReference { + typedef T type; +}; + +template struct RemoveReference { + typedef T type; +}; + +template struct RemoveReference { + typedef T type; +}; + +template <> struct RemoveReference { + typedef short type; +}; + +// like std::move +template typename RemoveReference::type&& Move(T&& t) { + return static_cast::type&&>(t); +} +%} + +%template(RemoveReferenceDouble) RemoveReference; +%template(RemoveReferenceFloat) RemoveReference; +%template(RemoveReferenceShort) RemoveReference; +%template(MoveFloat) Move; + + diff --git a/Examples/test-suite/python/cpp0x_rvalue_reference_runme.py b/Examples/test-suite/python/cpp0x_rvalue_reference_runme.py index acf296716..43fbc997e 100644 --- a/Examples/test-suite/python/cpp0x_rvalue_reference_runme.py +++ b/Examples/test-suite/python/cpp0x_rvalue_reference_runme.py @@ -16,7 +16,9 @@ a.setAref(ptr) if a.getAcopy() != 5: raise RunTimeError, ("after A::setAref(): int A::getAcopy() value is ", a.getAcopy(), " should be 5") -a.setAmove(ptr) +rvalueref = a.getAmove() + +a.setAmove(rvalueref) if a.getAcopy() != 5: raise RunTimeError, ("after A::setAmove(): int A::getAcopy() value is ", a.getAcopy(), " should be 5") diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg index 204cf4b2f..ecdf88b25 100644 --- a/Lib/csharp/csharp.swg +++ b/Lib/csharp/csharp.swg @@ -125,6 +125,10 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { %typemap(imtype, out="IntPtr") SWIGTYPE & "HandleRef" %typemap(cstype) SWIGTYPE & "$csclassname" +%typemap(ctype) SWIGTYPE && "void *" +%typemap(imtype, out="IntPtr") SWIGTYPE && "HandleRef" +%typemap(cstype) SWIGTYPE && "$csclassname" + /* pointer to a class member */ %typemap(ctype) SWIGTYPE (CLASS::*) "char *" %typemap(imtype) SWIGTYPE (CLASS::*) "string" @@ -397,6 +401,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0); return $null; } %} +%typemap(in, canthrow=1) SWIGTYPE && %{ $1 = ($1_ltype)$input; + if (!$1) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0); + return $null; + } %} %typemap(out) SWIGTYPE * %{ $result = (void *)$1; %} %typemap(out, fragment="SWIG_PackData") SWIGTYPE (CLASS::*) %{ char buf[128]; @@ -405,6 +414,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { $result = SWIG_csharp_string_callback(buf); %} %typemap(out) SWIGTYPE & %{ $result = (void *)$1; %} +%typemap(out) SWIGTYPE && %{ $result = (void *)$1; %} %typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE * %{ $result = ($1_ltype)$input; %} @@ -522,6 +532,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { SWIGTYPE, SWIGTYPE *, SWIGTYPE &, + SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" @@ -539,7 +550,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, error_msg); return $null; %} -%typemap(throws, canthrow=1) SWIGTYPE, SWIGTYPE &, SWIGTYPE *, SWIGTYPE [ANY] +%typemap(throws, canthrow=1) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [ANY] %{ (void)$1; SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, "C++ $1_type exception thrown"); return $null; %} @@ -570,7 +581,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { "$csinput" %typemap(csin) char *, char *&, char[ANY], char[] "$csinput" %typemap(csin) SWIGTYPE "$&csclassname.getCPtr($csinput)" -%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$csclassname.getCPtr($csinput)" +%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "$csclassname.getCPtr($csinput)" %typemap(csin) SWIGTYPE (CLASS::*) "$csclassname.getCMemberPtr($csinput)" /* The csout typemap is used for converting function return types from the return type @@ -653,6 +664,10 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { $csclassname ret = new $csclassname($imcall, $owner);$excode return ret; } +%typemap(csout, excode=SWIGEXCODE) SWIGTYPE && { + $csclassname ret = new $csclassname($imcall, $owner);$excode + return ret; + } %typemap(csout, excode=SWIGEXCODE) SWIGTYPE *, SWIGTYPE [] { IntPtr cPtr = $imcall; $csclassname ret = (cPtr == IntPtr.Zero) ? null : new $csclassname(cPtr, $owner);$excode @@ -666,7 +681,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { /* Properties */ -%typemap(csvarin, excode=SWIGEXCODE2) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ +%typemap(csvarin, excode=SWIGEXCODE2) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ set { $imcall;$excode } %} @@ -767,6 +782,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { $csclassname ret = new $csclassname($imcall, $owner);$excode return ret; } %} +%typemap(csvarout, excode=SWIGEXCODE2) SWIGTYPE && %{ + get { + $csclassname ret = new $csclassname($imcall, $owner);$excode + return ret; + } %} %typemap(csvarout, excode=SWIGEXCODE2) SWIGTYPE *, SWIGTYPE [] %{ get { IntPtr cPtr = $imcall; @@ -814,13 +834,13 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { /* Typemaps used for the generation of proxy and type wrapper class code */ -%typemap(csbase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" -%typemap(csclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "public class" -%typemap(cscode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" -%typemap(csimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "\nusing System;\nusing System.Runtime.InteropServices;\n" +%typemap(csbase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(csclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public class" +%typemap(cscode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(csimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "\nusing System;\nusing System.Runtime.InteropServices;\n" %typemap(csinterfaces) SWIGTYPE "IDisposable" -%typemap(csinterfaces) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" -%typemap(csinterfaces_derived) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(csinterfaces) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" +%typemap(csinterfaces_derived) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" // Proxy classes (base classes, ie, not derived classes) %typemap(csbody) SWIGTYPE %{ @@ -851,7 +871,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { %} // Typewrapper classes -%typemap(csbody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{ +%typemap(csbody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] %{ private HandleRef swigCPtr; internal $csclassname(IntPtr cPtr, bool futureUse) { diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index b9749bf01..bb644f9db 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3968,15 +3968,19 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para Delete(Namespaceprefix); Namespaceprefix = Swig_symbol_qualifiedscopename(0); if (error) $$ = 0; - } - | TEMPLATE cpptype idcolon { /* Explicit template instantiation */ + } + + /* Explicit template instantiation */ + | TEMPLATE cpptype idcolon { Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n"); - $$ = 0; - } - | EXTERN TEMPLATE cpptype idcolon { /* Explicit template instantiation without the translation unit */ + $$ = 0; + } + + /* Explicit template instantiation without the translation unit */ + | EXTERN TEMPLATE cpptype idcolon { Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n"); - $$ = 0; - } + $$ = 0; + } ; cpp_temp_possible: c_decl { @@ -4395,6 +4399,23 @@ cpp_conversion_operator : storage_class COPERATOR type pointer LPAREN parms RPAR Setattr($$,"conversion_operator","1"); add_symbols($$); } + | storage_class COPERATOR type LAND LPAREN parms RPAREN cpp_vend { + SwigType *decl; + $$ = new_node("cdecl"); + Setattr($$,"type",$3); + Setattr($$,"name",$2); + Setattr($$,"storage",$1); + decl = NewStringEmpty(); + SwigType_add_rvalue_reference(decl); + SwigType_add_function(decl,$6); + if ($8.qualifier) { + SwigType_push(decl,$8.qualifier); + } + Setattr($$,"decl",decl); + Setattr($$,"parms",$6); + Setattr($$,"conversion_operator","1"); + add_symbols($$); + } | storage_class COPERATOR type LPAREN parms RPAREN cpp_vend { String *t = NewStringEmpty(); @@ -4902,6 +4923,15 @@ declarator : pointer notso_direct_declarator { } $$.type = $1; } + | pointer LAND notso_direct_declarator { + $$ = $3; + SwigType_add_rvalue_reference($1); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } | direct_declarator { $$ = $1; if (!$$.type) $$.type = NewStringEmpty(); @@ -4920,7 +4950,7 @@ declarator : pointer notso_direct_declarator { /* Adds one S/R conflict */ $$ = $2; $$.type = NewStringEmpty(); - SwigType_add_reference($$.type); + SwigType_add_rvalue_reference($$.type); if ($2.type) { SwigType_push($$.type,$2.type); Delete($2.type); @@ -4990,6 +5020,15 @@ declarator : pointer notso_direct_declarator { } $$.type = $1; } + | pointer LAND PERIOD PERIOD PERIOD notso_direct_declarator { + $$ = $6; + SwigType_add_rvalue_reference($1); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } | PERIOD PERIOD PERIOD direct_declarator { $$ = $4; if (!$$.type) $$.type = NewStringEmpty(); @@ -5008,7 +5047,7 @@ declarator : pointer notso_direct_declarator { /* Adds one S/R conflict */ $$ = $5; $$.type = NewStringEmpty(); - SwigType_add_reference($$.type); + SwigType_add_rvalue_reference($$.type); if ($5.type) { SwigType_push($$.type,$5.type); Delete($5.type); @@ -5047,6 +5086,16 @@ declarator : pointer notso_direct_declarator { } $$.type = $1; } + | pointer idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator { + $$ = $8; + SwigType_add_memberpointer($1,$2); + SwigType_add_rvalue_reference($1); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } | idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator { SwigType *t = NewStringEmpty(); $$ = $7; @@ -5058,6 +5107,17 @@ declarator : pointer notso_direct_declarator { } $$.type = t; } + | idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator { + SwigType *t = NewStringEmpty(); + $$ = $7; + SwigType_add_memberpointer(t,$1); + SwigType_add_rvalue_reference(t); + if ($$.type) { + SwigType_push(t,$$.type); + Delete($$.type); + } + $$.type = t; + } ; notso_direct_declarator : idcolon { @@ -5191,6 +5251,13 @@ direct_declarator : idcolon { } SwigType_add_reference($$.type); } + | LPAREN LAND direct_declarator RPAREN { + $$ = $3; + if (!$$.type) { + $$.type = NewStringEmpty(); + } + SwigType_add_rvalue_reference($$.type); + } | LPAREN idcolon DSTAR direct_declarator RPAREN { SwigType *t; $$ = $4; @@ -5283,6 +5350,13 @@ abstract_declarator : pointer { $$.parms = 0; $$.have_parms = 0; } + | pointer LAND { + $$.type = $1; + SwigType_add_rvalue_reference($$.type); + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + } | pointer AND direct_abstract_declarator { $$ = $3; SwigType_add_reference($1); @@ -5292,6 +5366,15 @@ abstract_declarator : pointer { } $$.type = $1; } + | pointer LAND direct_abstract_declarator { + $$ = $3; + SwigType_add_rvalue_reference($1); + if ($$.type) { + SwigType_push($1,$$.type); + Delete($$.type); + } + $$.type = $1; + } | direct_abstract_declarator { $$ = $1; } @@ -5304,6 +5387,15 @@ abstract_declarator : pointer { Delete($2.type); } } + | LAND direct_abstract_declarator { + $$ = $2; + $$.type = NewStringEmpty(); + SwigType_add_rvalue_reference($$.type); + if ($2.type) { + SwigType_push($$.type,$2.type); + Delete($2.type); + } + } | AND { $$.id = 0; $$.parms = 0; @@ -5311,6 +5403,13 @@ abstract_declarator : pointer { $$.type = NewStringEmpty(); SwigType_add_reference($$.type); } + | LAND { + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + $$.type = NewStringEmpty(); + SwigType_add_rvalue_reference($$.type); + } | idcolon DSTAR { $$.type = NewStringEmpty(); SwigType_add_memberpointer($$.type,$1); @@ -5821,6 +5920,13 @@ valexpr : exprnum { $$ = $1; } $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); } } + | LPAREN expr LAND RPAREN expr %prec CAST { + $$ = $5; + if ($5.type != T_STRING) { + SwigType_add_rvalue_reference($2.val); + $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); + } + } | LPAREN expr pointer AND RPAREN expr %prec CAST { $$ = $6; if ($6.type != T_STRING) { @@ -5829,10 +5935,22 @@ valexpr : exprnum { $$ = $1; } $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val); } } + | LPAREN expr pointer LAND RPAREN expr %prec CAST { + $$ = $6; + if ($6.type != T_STRING) { + SwigType_push($2.val,$3); + SwigType_add_rvalue_reference($2.val); + $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val); + } + } | AND expr { $$ = $2; $$.val = NewStringf("&%s",$2.val); } + | LAND expr { + $$ = $2; + $$.val = NewStringf("&&%s",$2.val); + } | STAR expr { $$ = $2; $$.val = NewStringf("*%s",$2.val); diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 9f91f12d4..94abf58da 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1160,6 +1160,7 @@ public: break; } case T_REFERENCE: + case T_RVALUE_REFERENCE: case T_USER: case T_ARRAY: Clear(value); @@ -1930,6 +1931,7 @@ public: break; case T_POINTER: case T_REFERENCE: + case T_RVALUE_REFERENCE: case T_USER: if (is_shadow(t)) { return NewString(Char(is_shadow(t))); diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 208842121..25dfaea14 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -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; diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 69919ad55..a8abf88fe 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -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); diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 428bcf06d..07f27774d 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -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); diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index a44ecdf6d..6595944a0 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -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 { diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index cafecb9a6..a72a102aa 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -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 * diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index 19f14a2a0..f6baa5a83 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -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); } }