diff options
Diffstat (limited to 'Lib/swig.swg')
-rw-r--r-- | Lib/swig.swg | 119 |
1 files changed, 66 insertions, 53 deletions
diff --git a/Lib/swig.swg b/Lib/swig.swg index 6dc215dcf..db7e08cf6 100644 --- a/Lib/swig.swg +++ b/Lib/swig.swg @@ -9,20 +9,6 @@ * User Directives * ----------------------------------------------------------------------------- */ -/* Deprecated SWIG-1.1 directives */ - -#define %disabledoc %warn "104:%disabledoc is deprecated" -#define %enabledoc %warn "105:%enabledoc is deprecated" -#define %doconly %warn "106:%doconly is deprecated" -#define %style %warn "107:%style is deprecated" /##/ -#define %localstyle %warn "108:%localstyle is deprecated" /##/ -#define %title %warn "109:%title is deprecated" /##/ -#define %section %warn "110:%section is deprecated" /##/ -#define %subsection %warn "111:%subsection is deprecated" /##/ -#define %subsubsection %warn "112:%subsubsection is deprecated" /##/ -#define %new %warn "117:%new is deprecated. Use %newobject" -#define %text %insert("null") - /* Code insertion directives such as %wrapper %{ ... %} */ #define %begin %insert("begin") @@ -31,10 +17,6 @@ #define %wrapper %insert("wrapper") #define %init %insert("init") -/* Class extension */ - -#define %addmethods %warn "113:%addmethods is now %extend" %extend - /* %ignore directive */ #define %ignore %rename($ignore) @@ -42,9 +24,6 @@ /* Access control directives */ -#define %readonly %warn "114:%readonly is deprecated. Use %immutable; " %feature("immutable"); -#define %readwrite %warn "115:%readwrite is deprecated. Use %mutable; " %feature("immutable",""); - #define %immutable %feature("immutable") #define %noimmutable %feature("immutable","0") #define %clearimmutable %feature("immutable","") @@ -172,7 +151,7 @@ #define %novaluewrapper %feature("novaluewrapper") #define %clearnovaluewrapper %feature("novaluewrapper","") -/* Contract support - Experimental and undocumented */ +/* Contract support - Experimental */ #define %contract %feature("contract") #define %nocontract %feature("contract","0") #define %clearcontract %feature("contract","") @@ -268,7 +247,9 @@ static int NAME(TYPE x) { */ -%define %$not "not" %enddef +/* Note that when %$not is used with another macro, say %enum as follows: %$not %$enum, the result is "notmatch=enum" */ +%define %$not "not" %enddef + %define %$isenum "match"="enum" %enddef %define %$isenumitem "match"="enumitem" %enddef %define %$isaccess "match"="access" %enddef @@ -279,6 +260,7 @@ static int NAME(TYPE x) { %define %$isnamespace "match"="namespace" %enddef %define %$istemplate "match"="template" %enddef %define %$isconstant "match"="constant" %enddef /* %constant definition */ +%define %$isusing "match"="using" %enddef %define %$isunion "match$kind"="union" %enddef %define %$isfunction "match$kind"="function" %enddef @@ -358,6 +340,11 @@ static int NAME(TYPE x) { %define SWIG_TYPECHECK_STDUNISTRING 115 %enddef %define SWIG_TYPECHECK_UNISTRING 120 %enddef %define SWIG_TYPECHECK_CHAR 130 %enddef +/* Give std::string_view a slightly higher precedence because if there are + * overloaded forms then it may be more efficient to pass as std::string_view + * (e.g. to pass as std::string requires copying the data into a std::string). + */ +%define SWIG_TYPECHECK_STRINGVIEW 134 %enddef %define SWIG_TYPECHECK_STDSTRING 135 %enddef %define SWIG_TYPECHECK_STRING 140 %enddef %define SWIG_TYPECHECK_PAIR 150 %enddef @@ -445,15 +432,15 @@ namespace std { /* Set up the typemap for handling new return strings */ #ifdef __cplusplus -%typemap(newfree) char * "delete [] $1;"; +%typemap(newfree) char * "delete [] $1;" #else -%typemap(newfree) char * "free($1);"; +%typemap(newfree) char * "free($1);" #endif /* Default typemap for handling char * members */ #ifdef __cplusplus -%typemap(memberin) char * { +%typemap(memberin,fragment="<string.h>") char * { delete [] $1; if ($input) { $1 = ($1_type) (new char[strlen((const char *)$input)+1]); @@ -462,7 +449,7 @@ namespace std { $1 = 0; } } -%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * { +%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * { if ($input) { $1 = ($1_type) (new char[strlen((const char *)$input)+1]); strcpy((char *)$1, (const char *)$input); @@ -470,7 +457,7 @@ namespace std { $1 = 0; } } -%typemap(globalin) char * { +%typemap(globalin,fragment="<string.h>") char * { delete [] $1; if ($input) { $1 = ($1_type) (new char[strlen((const char *)$input)+1]); @@ -479,7 +466,7 @@ namespace std { $1 = 0; } } -%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * { +%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * { if ($input) { $1 = ($1_type) (new char[strlen((const char *)$input)+1]); strcpy((char *)$1, (const char *)$input); @@ -488,7 +475,7 @@ namespace std { } } #else -%typemap(memberin) char * { +%typemap(memberin,fragment="<string.h>") char * { free($1); if ($input) { $1 = ($1_type) malloc(strlen((const char *)$input)+1); @@ -497,7 +484,7 @@ namespace std { $1 = 0; } } -%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * { +%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * { if ($input) { $1 = ($1_type) malloc(strlen((const char *)$input)+1); strcpy((char *)$1, (const char *)$input); @@ -505,7 +492,7 @@ namespace std { $1 = 0; } } -%typemap(globalin) char * { +%typemap(globalin,fragment="<string.h>") char * { free($1); if ($input) { $1 = ($1_type) malloc(strlen((const char *)$input)+1); @@ -514,7 +501,7 @@ namespace std { $1 = 0; } } -%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * { +%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * { if ($input) { $1 = ($1_type) malloc(strlen((const char *)$input)+1); strcpy((char *)$1, (const char *)$input); @@ -527,7 +514,7 @@ namespace std { /* Character array handling */ -%typemap(memberin) char [ANY] { +%typemap(memberin,fragment="<string.h>") char [ANY] { if($input) { strncpy((char*)$1, (const char *)$input, $1_dim0-1); $1[$1_dim0-1] = 0; @@ -536,7 +523,7 @@ namespace std { } } -%typemap(globalin) char [ANY] { +%typemap(globalin,fragment="<string.h>") char [ANY] { if($input) { strncpy((char*)$1, (const char *)$input, $1_dim0-1); $1[$1_dim0-1] = 0; @@ -545,12 +532,12 @@ namespace std { } } -%typemap(memberin) char [] { +%typemap(memberin,fragment="<string.h>") char [] { if ($input) strcpy((char *)$1, (const char *)$input); else $1[0] = 0; } -%typemap(globalin) char [] { +%typemap(globalin,fragment="<string.h>") char [] { if ($input) strcpy((char *)$1, (const char *)$input); else $1[0] = 0; } @@ -599,6 +586,10 @@ namespace std { * Runtime code * ----------------------------------------------------------------------------- */ + +%insert("runtime") "swiglabels.swg" + + /* The SwigValueWrapper class */ /* @@ -649,33 +640,53 @@ namespace std { * arg1 = *inarg1; // Assignment from a pointer * arg1 = Vector(1,2,3); // Assignment from a value * + * SwigValueWrapper is a drop in replacement to modify normal value semantics by + * using the heap instead of the stack to copy/move the underlying object it is + * managing. Smart pointers also manage an underlying object on the heap, so + * SwigValueWrapper has characteristics of a smart pointer. The reset function + * is specific smart pointer functionality, but cannot be a non-static member as + * when SWIG modifies typemap code it assumes non-static member function calls + * are routed to the underlying object, changing for example $1.f() to (&x)->f(). + * The reset function was added as an optimisation to avoid some copying/moving + * and to take ownership of an object already created on the heap. + * * The class offers a strong guarantee of exception safety. - * With regards to the implementation, the private SwigMovePointer nested class is - * a simple smart pointer with move semantics, much like std::auto_ptr. + * With regards to the implementation, the private SwigSmartPointer nested class is + * a simple smart pointer providing exception safety, much like std::auto_ptr. * * This wrapping technique was suggested by William Fulton and is henceforth * known as the "Fulton Transform" :-). */ #ifdef __cplusplus -%insert("runtime") %{ +// Placed in the header section to ensure the language specific header files are +// the first included headers and not <utility> +%insert("header") %{ #ifdef __cplusplus +#include <utility> /* SwigValueWrapper is described in swig.swg */ template<typename T> class SwigValueWrapper { - struct SwigMovePointer { + struct SwigSmartPointer { T *ptr; - SwigMovePointer(T *p) : ptr(p) { } - ~SwigMovePointer() { delete ptr; } - SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } + SwigSmartPointer(T *p) : ptr(p) { } + ~SwigSmartPointer() { delete ptr; } + SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } + void reset(T *p) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = p; } } pointer; SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs); SwigValueWrapper(const SwigValueWrapper<T>& rhs); public: SwigValueWrapper() : pointer(0) { } - SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; } + SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; } +#if __cplusplus >=201103L + SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; } + operator T&&() const { return std::move(*pointer.ptr); } +#else operator T&() const { return *pointer.ptr; } - T *operator&() { return pointer.ptr; } -};%} +#endif + T *operator&() const { return pointer.ptr; } + static void reset(SwigValueWrapper& t, T *p) { t.pointer.reset(p); } +}; /* * SwigValueInit() is a generic initialisation solution as the following approach: @@ -686,16 +697,18 @@ public: * * unsigned int c_result = unsigned int(); */ -%insert("runtime") %{ template <typename T> T SwigValueInit() { return T(); } + +#if __cplusplus >=201103L +# define SWIG_STD_MOVE(OBJ) std::move(OBJ) +#else +# define SWIG_STD_MOVE(OBJ) OBJ +#endif + #endif %} #endif -/* The swiglabels */ - -%insert("runtime") "swiglabels.swg" - - +%insert("runtime") "swigcompat.swg" |