aboutsummaryrefslogtreecommitdiff
path: root/Lib/csharp
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/csharp')
-rw-r--r--Lib/csharp/argcargv.i76
-rw-r--r--Lib/csharp/arrays_csharp.i37
-rw-r--r--Lib/csharp/boost_intrusive_ptr.i4
-rw-r--r--Lib/csharp/boost_shared_ptr.i6
-rw-r--r--Lib/csharp/csharp.swg89
-rw-r--r--Lib/csharp/csharphead.swg2
-rw-r--r--Lib/csharp/csharpkw.swg4
-rw-r--r--Lib/csharp/std_array.i71
-rw-r--r--Lib/csharp/std_auto_ptr.i51
-rw-r--r--Lib/csharp/std_list.i2
-rw-r--r--Lib/csharp/std_map.i30
-rw-r--r--Lib/csharp/std_set.i11
-rw-r--r--Lib/csharp/std_string.i8
-rw-r--r--Lib/csharp/std_string_view.i116
-rw-r--r--Lib/csharp/std_unique_ptr.i38
-rw-r--r--Lib/csharp/std_unordered_map.i306
-rw-r--r--Lib/csharp/std_unordered_set.i320
-rw-r--r--Lib/csharp/std_vector.i29
-rw-r--r--Lib/csharp/std_wstring.i66
-rw-r--r--Lib/csharp/swigmove.i16
-rw-r--r--Lib/csharp/typemaps.i49
-rw-r--r--Lib/csharp/wchar.i266
22 files changed, 1433 insertions, 164 deletions
diff --git a/Lib/csharp/argcargv.i b/Lib/csharp/argcargv.i
new file mode 100644
index 000000000..2dae1f6dc
--- /dev/null
+++ b/Lib/csharp/argcargv.i
@@ -0,0 +1,76 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(cstype) (int ARGC, char **ARGV) "string[]"
+%typemap(imtype) (int ARGC, char **ARGV) "global::System.IntPtr"
+%typemap(ctype) (int ARGC, char **ARGV) "void*"
+%typemap(csin) (int ARGC, char **ARGV) "$modulePINVOKE.SWIG_csharp_string_array_to_c($csinput.Length, $csinput)"
+%pragma(csharp) imclasscode=%{
+ [global::System.Runtime.InteropServices.DllImport("$module", EntryPoint="SWIG_csharp_string_array_to_c")]
+ public static extern global::System.IntPtr SWIG_csharp_string_array_to_c(int len, [global::System.Runtime.InteropServices.In,global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPArray, ArraySubType=global::System.Runtime.InteropServices.UnmanagedType.LPStr, SizeParamIndex=0)] string[] array);
+%}
+%fragment("SWIG_csharp_string_array", "header") %{
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct { int len; char* array[1]; } SWIG_csharp_string_array;
+
+static void* SWIG_csharp_string_array_free(SWIG_csharp_string_array *arr) {
+ if (arr != SWIG_NULLPTR) {
+ int i;
+ for(i = 0; i < arr->len; i++) {
+ free(arr->array[i]);
+ }
+ free(arr);
+ }
+ return SWIG_NULLPTR;
+}
+
+SWIGEXPORT void* SWIGSTDCALL SWIG_csharp_string_array_to_c(int len, void *array) {
+ int i;
+ size_t alen, slen;
+ char *p, **ptr;
+ SWIG_csharp_string_array *ret;
+ /* We don't need to add one to len for the terminating NULL here because
+ * SWIG_csharp_string_array includes one element already.
+ */
+ alen = sizeof(SWIG_csharp_string_array) + sizeof(char *) * len;
+ ret = (SWIG_csharp_string_array *)malloc(alen);
+ if (ret == SWIG_NULLPTR) {
+ SWIG_CSharpSetPendingException(SWIG_CSharpOutOfMemoryException, "fail to duplicate array.");
+ return SWIG_NULLPTR;
+ }
+ memset(ret, 0, alen);
+ ret->len = len;
+ ptr = (char **)array;
+ for(i = 0; i < len; i++) {
+ slen = strlen(ptr[i]) + 1;
+ p = (char*)malloc(slen);
+ if (p == SWIG_NULLPTR) {
+ SWIG_CSharpSetPendingException(SWIG_CSharpOutOfMemoryException, "fail to alloc a string.");
+ return SWIG_csharp_string_array_free(ret);
+ }
+ memcpy(p, ptr[i], slen);
+ ret->array[i] = p;
+ }
+ ret->array[i] = SWIG_NULLPTR;
+ return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
+%}
+
+%typemap(in, canthrow=1, fragment="SWIG_csharp_string_array") (int ARGC, char **ARGV) %{
+ SWIG_csharp_string_array *arr = (SWIG_csharp_string_array*)$input;
+ if (arr != SWIG_NULLPTR) {
+ $1 = ($1_ltype)arr->len;
+ $2 = ($2_ltype)arr->array;
+ }
+%}
+
+%typemap(freearg, fragment="SWIG_csharp_string_array") (int ARGC, char **ARGV) %{
+ SWIG_csharp_string_array_free((SWIG_csharp_string_array*)$input);
+%}
diff --git a/Lib/csharp/arrays_csharp.i b/Lib/csharp/arrays_csharp.i
index 861da8386..00ded7187 100644
--- a/Lib/csharp/arrays_csharp.i
+++ b/Lib/csharp/arrays_csharp.i
@@ -49,8 +49,17 @@
* %csmethodmodifiers myArrayCopy "public unsafe";
* void myArrayCopy( int *sourceArray, int* targetArray, int nitems );
*
+ * long type
+ * ---------
+ * Unlike other primitive types, the sizeof(long) varies considerably from one
+ * platform to another. The sizeof(long) in the unmanaged layer must match the
+ * number of bytes used in the managed layer. A check is implemented via the
+ * "long_check_wordsize" fragment which results in a compile time error upon an
+ * inconsistent match. Use the SWIGWORDSIZE64 macro to target 64-bit long.
+ * For easiest portability, avoid using long!
* ----------------------------------------------------------------------------- */
+
%define CSHARP_ARRAYS( CTYPE, CSTYPE )
// input only arrays
@@ -94,16 +103,23 @@ CSHARP_ARRAYS(short, short)
CSHARP_ARRAYS(unsigned short, ushort)
CSHARP_ARRAYS(int, int)
CSHARP_ARRAYS(unsigned int, uint)
-// FIXME - on Unix 64 bit, long is 8 bytes but is 4 bytes on Windows 64 bit.
-// How can this be handled sensibly?
-// See e.g. http://www.xml.com/ldd/chapter/book/ch10.html
-CSHARP_ARRAYS(long, int)
-CSHARP_ARRAYS(unsigned long, uint)
CSHARP_ARRAYS(long long, long)
CSHARP_ARRAYS(unsigned long long, ulong)
CSHARP_ARRAYS(float, float)
CSHARP_ARRAYS(double, double)
+// 32-bit/64-bit architecture specific typemaps - special handling to ensure sizeof(long) on C side matches size used on C# side
+#if !defined(SWIGWORDSIZE64)
+CSHARP_ARRAYS(long, int)
+CSHARP_ARRAYS(unsigned long, uint)
+#else
+CSHARP_ARRAYS(long, long)
+CSHARP_ARRAYS(unsigned long, ulong)
+#endif
+%typemap(in, fragment="long_check_wordsize") long INPUT[], unsigned long INPUT[] "$1 = $input;"
+%typemap(in, fragment="long_check_wordsize") long OUTPUT[], unsigned long OUTPUT[] "$1 = $input;"
+%typemap(in, fragment="long_check_wordsize") long INOUT[], unsigned long INOUT[] "$1 = $input;"
+
// By default C# will marshal bools as 4 bytes
// UnmanagedType.I1 will change this to 1 byte
// FIXME - When running on mono ArraySubType appears to be ignored and bools will be marshalled as 4-byte
@@ -169,11 +185,18 @@ CSHARP_ARRAYS_FIXED(short, short)
CSHARP_ARRAYS_FIXED(unsigned short, ushort)
CSHARP_ARRAYS_FIXED(int, int)
CSHARP_ARRAYS_FIXED(unsigned int, uint)
-CSHARP_ARRAYS_FIXED(long, int)
-CSHARP_ARRAYS_FIXED(unsigned long, uint)
CSHARP_ARRAYS_FIXED(long long, long)
CSHARP_ARRAYS_FIXED(unsigned long long, ulong)
CSHARP_ARRAYS_FIXED(float, float)
CSHARP_ARRAYS_FIXED(double, double)
CSHARP_ARRAYS_FIXED(bool, bool)
+// 32-bit/64-bit architecture specific typemaps - special handling to ensure sizeof(long) on C side matches size used on C# side
+#ifdef !SWIGWORDSIZE64
+CSHARP_ARRAYS_FIXED(long, int)
+CSHARP_ARRAYS_FIXED(unsigned long, uint)
+#else
+CSHARP_ARRAYS_FIXED(long, long)
+CSHARP_ARRAYS_FIXED(unsigned long, ulong)
+#endif
+%typemap(in, fragment="long_check_wordsize") long FIXED[], unsigned long FIXED[] "$1 = $input;"
diff --git a/Lib/csharp/boost_intrusive_ptr.i b/Lib/csharp/boost_intrusive_ptr.i
index fa3f53a20..355a910cf 100644
--- a/Lib/csharp/boost_intrusive_ptr.i
+++ b/Lib/csharp/boost_intrusive_ptr.i
@@ -32,7 +32,7 @@
%}
%typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{
//plain value(out)
- $1_ltype* resultp = new $1_ltype(($1_ltype &)$1);
+ $1_ltype* resultp = new $1_ltype($1);
intrusive_ptr_add_ref(resultp);
*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >());
%}
@@ -372,7 +372,7 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
// plain pointer
%typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
diff --git a/Lib/csharp/boost_shared_ptr.i b/Lib/csharp/boost_shared_ptr.i
index 508c0ec14..d47fab558 100644
--- a/Lib/csharp/boost_shared_ptr.i
+++ b/Lib/csharp/boost_shared_ptr.i
@@ -29,10 +29,10 @@
}
$1 = *argp; %}
%typemap(out) CONST TYPE
-%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
%typemap(directorin) CONST TYPE
-%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
%typemap(directorout) CONST TYPE
%{ if (!$input) {
@@ -122,7 +122,7 @@
%typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
%{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
%typemap(out, fragment="SWIG_null_deleter") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
-%{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
+%{ $result = ($1 && *$1) ? new $*1_ltype(*$1) : 0;
if ($owner) delete $1; %}
%typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg
index 832206386..fffde505c 100644
--- a/Lib/csharp/csharp.swg
+++ b/Lib/csharp/csharp.swg
@@ -82,8 +82,8 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(ctype) unsigned short, const unsigned short & "unsigned short"
%typemap(ctype) int, const int & "int"
%typemap(ctype) unsigned int, const unsigned int & "unsigned int"
-%typemap(ctype) long, const long & "long"
-%typemap(ctype) unsigned long, const unsigned long & "unsigned long"
+%typemap(ctype) long, const long & "int"
+%typemap(ctype) unsigned long, const unsigned long & "unsigned int"
%typemap(ctype) long long, const long long & "long long"
%typemap(ctype) unsigned long long, const unsigned long long & "unsigned long long"
%typemap(ctype) float, const float & "float"
@@ -201,9 +201,9 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(directorin) short "$input = $1;"
%typemap(directorin) unsigned short "$input = $1;"
%typemap(directorin) int "$input = $1;"
-%typemap(directorin) unsigned int "$input = $1;"
+%typemap(directorin) unsigned int "$input = (unsigned int)$1;"
%typemap(directorin) long "$input = $1;"
-%typemap(directorin) unsigned long "$input = (unsigned long)$1;"
+%typemap(directorin) unsigned long "$input = $1;"
%typemap(directorin) long long "$input = $1;"
%typemap(directorin) unsigned long long "$input = $1;"
%typemap(directorin) float "$input = $1;"
@@ -246,9 +246,9 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(out) short %{ $result = $1; %}
%typemap(out) unsigned short %{ $result = $1; %}
%typemap(out) int %{ $result = $1; %}
-%typemap(out) unsigned int %{ $result = $1; %}
+%typemap(out) unsigned int %{ $result = (unsigned int)$1; %}
%typemap(out) long %{ $result = $1; %}
-%typemap(out) unsigned long %{ $result = (unsigned long)$1; %}
+%typemap(out) unsigned long %{ $result = $1; %}
%typemap(out) long long %{ $result = $1; %}
%typemap(out) unsigned long long %{ $result = $1; %}
%typemap(out) float %{ $result = $1; %}
@@ -327,7 +327,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(directorin) const short & "$input = $1;"
%typemap(directorin) const unsigned short & "$input = $1;"
%typemap(directorin) const int & "$input = $1;"
-%typemap(directorin) const unsigned int & "$input = $1;"
+%typemap(directorin) const unsigned int & "$input = (unsigned int)$1;"
%typemap(directorin) const long & "$input = $1;"
%typemap(directorin) const unsigned long & "$input = $1;"
%typemap(directorin) const long long & "$input = $1;"
@@ -373,9 +373,9 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(out) const short & %{ $result = *$1; %}
%typemap(out) const unsigned short & %{ $result = *$1; %}
%typemap(out) const int & %{ $result = *$1; %}
-%typemap(out) const unsigned int & %{ $result = *$1; %}
+%typemap(out) const unsigned int & %{ $result = (unsigned int)*$1; %}
%typemap(out) const long & %{ $result = *$1; %}
-%typemap(out) const unsigned long & %{ $result = (unsigned long)*$1; %}
+%typemap(out) const unsigned long & %{ $result = *$1; %}
%typemap(out) const long long & %{ $result = *$1; %}
%typemap(out) const unsigned long long & %{ $result = *$1; %}
%typemap(out) const float & %{ $result = *$1; %}
@@ -399,7 +399,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(out) SWIGTYPE
#ifdef __cplusplus
-%{ $result = new $1_ltype((const $1_ltype &)$1); %}
+%{ $result = new $1_ltype($1); %}
#else
{
$&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
@@ -409,7 +409,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
#endif
%typemap(directorin) SWIGTYPE
-%{ $input = (void *)new $1_ltype((const $1_ltype &)$1); %}
+%{ $input = (void *)new $1_ltype(SWIG_STD_MOVE($1)); %}
%typemap(csdirectorin) SWIGTYPE "new $&csclassname($iminput, true)"
%typemap(csdirectorout) SWIGTYPE "$&csclassname.getCPtr($cscall).Handle"
@@ -420,14 +420,15 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%}
%typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input;
if (!$1) {
- SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0);
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type is null", 0);
return $null;
} %}
-%typemap(in, canthrow=1) SWIGTYPE && %{ $1 = ($1_ltype)$input;
+%typemap(in, canthrow=1, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = ($1_ltype)$input;
if (!$1) {
- SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0);
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type is null", 0);
return $null;
- } %}
+ }
+ rvrdeleter.reset($1); %}
%typemap(out) SWIGTYPE * %{ $result = (void *)$1; %}
%typemap(out, fragment="SWIG_PackData") SWIGTYPE (CLASS::*) %{
char buf[128];
@@ -578,7 +579,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
unsigned long,
unsigned short
%{ char error_msg[256];
- sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
+ SWIG_snprintf(error_msg, sizeof(error_msg), "C++ $1_type exception thrown, value: %d", $1);
SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, error_msg);
return $null; %}
@@ -613,7 +614,8 @@ 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 &&, SWIGTYPE [] "$csclassname.getCPtr($csinput)"
+%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$csclassname.getCPtr($csinput)"
+%typemap(csin) SWIGTYPE && "$csclassname.swigRelease($csinput)"
%typemap(csin) SWIGTYPE (CLASS::*) "$csclassname.getCMemberPtr($csinput)"
/* The csout typemap is used for converting function return types from the return type
@@ -875,6 +877,15 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
global::System.IntPtr ret = $imcall;$excode
return ret;
}
+%typemap(csvarin, excode=SWIGEXCODE2) void *VOID_INT_PTR %{
+ set {
+ $imcall;$excode
+ } %}
+%typemap(csvarout, excode=SWIGEXCODE2) void *VOID_INT_PTR %{
+ get {
+ global::System.IntPtr ret = $imcall;$excode
+ return ret;
+ } %}
%typemap(csdirectorin) void *VOID_INT_PTR "$iminput"
%typemap(csdirectorout) void *VOID_INT_PTR "$cscall"
@@ -885,6 +896,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(csinterfaces) SWIGTYPE "global::System.IDisposable"
%typemap(csinterfaces) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
%typemap(csinterfaces_derived) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
+%typemap(csinterfacemodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public interface"
// csbody typemaps... these are in macros so that the visibility of the methods can be easily changed by users.
@@ -903,6 +915,19 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+ if (obj != null) {
+ if (!obj.swigCMemOwn)
+ throw new global::System.ApplicationException("Cannot release ownership as memory is not owned");
+ global::System.Runtime.InteropServices.HandleRef ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ obj.Dispose();
+ return ptr;
+ } else {
+ return new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
+ }
+ }
%}
// Derived proxy classes
@@ -916,6 +941,19 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+ if (obj != null) {
+ if (!obj.swigCMemOwn)
+ throw new global::System.ApplicationException("Cannot release ownership as memory is not owned");
+ global::System.Runtime.InteropServices.HandleRef ptr = obj.swigCPtr;
+ obj.swigCMemOwn = false;
+ obj.Dispose();
+ return ptr;
+ } else {
+ return new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
+ }
+ }
%}
%enddef
@@ -935,6 +973,10 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
}
+
+ CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+ return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
+ }
%}
%typemap(csbody) TYPE (CLASS::*) %{
@@ -1020,10 +1062,17 @@ SWIG_CSBODY_TYPEWRAPPER(internal, protected, internal, SWIGTYPE)
%pragma(csharp) imclassclassmodifiers="class"
%pragma(csharp) moduleclassmodifiers="public class"
-/* Some ANSI C typemaps */
+/* 64-bit architecture specific typemaps */
+#if defined(SWIGWORDSIZE64)
+%apply long long { long };
+%apply unsigned long long { unsigned long };
+%apply const long long & { const long & };
+%apply const unsigned long long & { const unsigned long & };
+#endif
-%apply unsigned long { size_t };
-%apply const unsigned long & { const size_t & };
+/* size_t maps to C# 32-bit uint type */
+%apply unsigned int { size_t };
+%apply const unsigned int & { const size_t & };
/* Array reference typemaps */
%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
diff --git a/Lib/csharp/csharphead.swg b/Lib/csharp/csharphead.swg
index 7db4c0e3c..56a019bd5 100644
--- a/Lib/csharp/csharphead.swg
+++ b/Lib/csharp/csharphead.swg
@@ -335,5 +335,5 @@ SWIGEXPORT void SWIGSTDCALL SWIGRegisterStringCallback_$module(SWIG_CSharpString
%insert(runtime) %{
/* Contract support */
-#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, msg, ""); return nullreturn; } else
+#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, msg, ""); return nullreturn; } } while (0)
%}
diff --git a/Lib/csharp/csharpkw.swg b/Lib/csharp/csharpkw.swg
index 824f61874..1904fce94 100644
--- a/Lib/csharp/csharpkw.swg
+++ b/Lib/csharp/csharpkw.swg
@@ -2,9 +2,9 @@
#define CSHARP_CSHARPKW_SWG_
/* Warnings for C# keywords */
-#define CSHARPKW(x) %keywordwarn("'" `x` "' is a C# keyword, renaming to '" `x` "_'",rename="%s_") `x`
+#define CSHARPKW(x) %keywordwarn("'" `x` "' is a C# keyword",rename="%s_") `x`
-#define CSHARPCLASSKW(x) %keywordwarn("'" `x` "' is a special method name used in the C# wrapper classes, class renamed to '" `x` "_'",%$isclass,rename="%s_") `x`
+#define CSHARPCLASSKW(x) %keywordwarn("'" `x` "' is a special method name used in the C# wrapper classes",%$isclass,rename="%s_") `x`
/*
from
diff --git a/Lib/csharp/std_array.i b/Lib/csharp/std_array.i
index a4f0f9640..87b1b8956 100644
--- a/Lib/csharp/std_array.i
+++ b/Lib/csharp/std_array.i
@@ -6,37 +6,37 @@
* The C# wrapper is made to look and feel like a C# System.Collections.Generic.IReadOnlyList<> collection.
* ----------------------------------------------------------------------------- */
-%{
-#include <algorithm>
-#include <array>
-#include <stdexcept>
-%}
-
%include <std_common.i>
-%define SWIG_STD_ARRAY_INTERNAL(T, N)
-%typemap(csinterfaces) std::array< T, N > "global::System.IDisposable, global::System.Collections.IEnumerable\n , global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>\n";
+%define SWIG_STD_ARRAY_INTERNAL(CTYPE, N)
+%typemap(csinterfaces) std::array< CTYPE, N > "global::System.IDisposable, global::System.Collections.IEnumerable\n , global::System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)>\n"
%proxycode %{
public $csclassname(global::System.Collections.ICollection c) : this() {
if (c == null)
throw new global::System.ArgumentNullException("c");
- int end = global::System.Math.Min(this.Count, c.Count);
+ int count = this.Count;
int i = 0;
- foreach ($typemap(cstype, T) elem in c) {
- if (i >= end)
+ foreach ($typemap(cstype, CTYPE) element in c) {
+ if (i >= count)
break;
- this[i++] = elem;
+ this[i++] = element;
}
}
- public int Count {
+ public bool IsFixedSize {
get {
- return (int)size();
+ return true;
}
}
- public $typemap(cstype, T) this[int index] {
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public $typemap(cstype, CTYPE) this[int index] {
get {
return getitem(index);
}
@@ -51,17 +51,29 @@
}
}
- public void CopyTo($typemap(cstype, T)[] array)
+ public int Count {
+ get {
+ return (int)size();
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return false;
+ }
+ }
+
+ public void CopyTo($typemap(cstype, CTYPE)[] array)
{
CopyTo(0, array, 0, this.Count);
}
- public void CopyTo($typemap(cstype, T)[] array, int arrayIndex)
+ public void CopyTo($typemap(cstype, CTYPE)[] array, int arrayIndex)
{
CopyTo(0, array, arrayIndex, this.Count);
}
- public void CopyTo(int index, $typemap(cstype, T)[] array, int arrayIndex, int count)
+ public void CopyTo(int index, $typemap(cstype, CTYPE)[] array, int arrayIndex, int count)
{
if (array == null)
throw new global::System.ArgumentNullException("array");
@@ -79,7 +91,13 @@
array.SetValue(getitemcopy(index+i), arrayIndex+i);
}
- global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>.GetEnumerator() {
+ public $typemap(cstype, CTYPE)[] ToArray() {
+ $typemap(cstype, CTYPE)[] array = new $typemap(cstype, CTYPE)[this.Count];
+ this.CopyTo(array);
+ return array;
+ }
+
+ global::System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)>.GetEnumerator() {
return new $csclassnameEnumerator(this);
}
@@ -97,7 +115,7 @@
/// collection but not when one of the elements of the collection is modified as it is a bit
/// tricky to detect unmanaged code that modifies the collection under our feet.
public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator
- , global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)>
+ , global::System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)>
{
private $csclassname collectionRef;
private int currentIndex;
@@ -112,7 +130,7 @@
}
// Type-safe iterator Current
- public $typemap(cstype, T) Current {
+ public $typemap(cstype, CTYPE) Current {
get {
if (currentIndex == -1)
throw new global::System.InvalidOperationException("Enumeration not started.");
@@ -120,7 +138,7 @@
throw new global::System.InvalidOperationException("Enumeration finished.");
if (currentObject == null)
throw new global::System.InvalidOperationException("Collection modified.");
- return ($typemap(cstype, T))currentObject;
+ return ($typemap(cstype, CTYPE))currentObject;
}
}
@@ -161,7 +179,7 @@
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
- typedef T value_type;
+ typedef CTYPE value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
@@ -180,7 +198,7 @@
void swap(array& other);
%extend {
- T getitemcopy(int index) throw (std::out_of_range) {
+ CTYPE getitemcopy(int index) throw (std::out_of_range) {
if (index>=0 && index<(int)$self->size())
return (*$self)[index];
else
@@ -213,6 +231,11 @@
}
%enddef
+%{
+#include <array>
+#include <algorithm>
+#include <stdexcept>
+%}
%csmethodmodifiers std::array::empty "private"
%csmethodmodifiers std::array::getitemcopy "private"
diff --git a/Lib/csharp/std_auto_ptr.i b/Lib/csharp/std_auto_ptr.i
index d7e5f167e..da15df3e9 100644
--- a/Lib/csharp/std_auto_ptr.i
+++ b/Lib/csharp/std_auto_ptr.i
@@ -1,25 +1,38 @@
-/*
- The typemaps here allow to handle functions returning std::auto_ptr<>,
- which is the most common use of this type. If you have functions taking it
- as parameter, these typemaps can't be used for them and you need to do
- something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
%define %auto_ptr(TYPE)
-%typemap (ctype) std::auto_ptr<TYPE > "void *"
-%typemap (imtype, out="System.IntPtr") std::auto_ptr<TYPE > "HandleRef"
-%typemap (cstype) std::auto_ptr<TYPE > "$typemap(cstype, TYPE)"
-%typemap (out) std::auto_ptr<TYPE > %{
- $result = (void *)$1.release();
+%typemap (ctype) std::auto_ptr< TYPE > "void *"
+%typemap (imtype, out="System.IntPtr") std::auto_ptr< TYPE > "global::System.Runtime.InteropServices.HandleRef"
+%typemap (cstype) std::auto_ptr< TYPE > "$typemap(cstype, TYPE)"
+
+%typemap(in) std::auto_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(csin) std::auto_ptr< TYPE > "$typemap(cstype, TYPE).swigRelease($csinput)"
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ $result = (void *)$1.release();
%}
-%typemap(csout, excode=SWIGEXCODE) std::auto_ptr<TYPE > {
- System.IntPtr cPtr = $imcall;
- $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
- return ret;
- }
-%template() std::auto_ptr<TYPE >;
+
+%typemap(csout, excode=SWIGEXCODE) std::auto_ptr< TYPE > {
+ System.IntPtr cPtr = $imcall;
+ $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
+ return ret;
+ }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::auto_ptr< TYPE > ""
+
+%template() std::auto_ptr< TYPE >;
%enddef
namespace std {
- template <class T> class auto_ptr {};
-}
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/csharp/std_list.i b/Lib/csharp/std_list.i
index 674aba0ab..cf6f20238 100644
--- a/Lib/csharp/std_list.i
+++ b/Lib/csharp/std_list.i
@@ -19,7 +19,7 @@
// MACRO for use within the std::list class body
%define SWIG_STD_LIST_MINIMUM_INTERNAL(CSINTERFACE, CTYPE...)
-%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n";
+%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n"
%apply void *VOID_INT_PTR { std::list< CTYPE >::iterator * };
diff --git a/Lib/csharp/std_map.i b/Lib/csharp/std_map.i
index e538a03a1..4f447422a 100644
--- a/Lib/csharp/std_map.i
+++ b/Lib/csharp/std_map.i
@@ -26,7 +26,7 @@
/* K is the C++ key type, T is the C++ value type */
%define SWIG_STD_MAP_INTERNAL(K, T, C)
-%typemap(csinterfaces) std::map< K, T, C > "global::System.IDisposable \n , global::System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n";
+%typemap(csinterfaces) std::map< K, T, C > "global::System.IDisposable \n , global::System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n"
%proxycode %{
public $typemap(cstype, T) this[$typemap(cstype, K) key] {
@@ -48,6 +48,12 @@
return false;
}
+ public bool IsEmpty {
+ get {
+ return empty();
+ }
+ }
+
public int Count {
get {
return (int)size();
@@ -236,7 +242,11 @@
}
void setitem(const key_type& key, const mapped_type& x) {
+%#ifdef __cpp_lib_map_try_emplace
+ (*$self).insert_or_assign(key, x);
+%#else
(*$self)[key] = x;
+%#endif
}
bool ContainsKey(const key_type& key) {
@@ -269,12 +279,14 @@
}
const key_type& get_next_key(std::map< K, T, C >::iterator *swigiterator) {
+ (void)$self;
std::map< K, T, C >::iterator iter = *swigiterator;
(*swigiterator)++;
return (*iter).first;
}
void destroy_iterator(std::map< K, T, C >::iterator *swigiterator) {
+ (void)$self;
delete swigiterator;
}
}
@@ -282,6 +294,7 @@
%enddef
+%csmethodmodifiers std::map::empty "private"
%csmethodmodifiers std::map::size "private"
%csmethodmodifiers std::map::getitem "private"
%csmethodmodifiers std::map::setitem "private"
@@ -295,18 +308,3 @@ namespace std {
SWIG_STD_MAP_INTERNAL(K, T, C)
};
}
-
-
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
diff --git a/Lib/csharp/std_set.i b/Lib/csharp/std_set.i
index 82f010aff..480a24cc7 100644
--- a/Lib/csharp/std_set.i
+++ b/Lib/csharp/std_set.i
@@ -16,6 +16,7 @@
#include <stdexcept>
%}
+%csmethodmodifiers std::set::empty "private"
%csmethodmodifiers std::set::size "private"
%csmethodmodifiers std::set::getitem "private"
%csmethodmodifiers std::set::create_iterator_begin "private"
@@ -28,7 +29,7 @@ namespace std {
template <class T>
class set {
-%typemap(csinterfaces) std::set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n";
+%typemap(csinterfaces) std::set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n"
%proxycode %{
void global::System.Collections.Generic.ICollection<$typemap(cstype, T)>.Add($typemap(cstype, T) item) {
((global::System.Collections.Generic.ISet<$typemap(cstype, T)>)this).Add(item);
@@ -44,6 +45,12 @@ class set {
}
}
+ public bool IsEmpty {
+ get {
+ return empty();
+ }
+ }
+
public int Count {
get {
return (int)size();
@@ -297,12 +304,14 @@ class set {
}
const key_type& get_next(std::set<T>::iterator *swigiterator) {
+ (void)$self;
std::set<T>::iterator iter = *swigiterator;
(*swigiterator)++;
return *iter;
}
void destroy_iterator(std::set<T>::iterator *swigiterator) {
+ (void)$self;
delete swigiterator;
}
}
diff --git a/Lib/csharp/std_string.i b/Lib/csharp/std_string.i
index 5f8fa44cb..c8920c09e 100644
--- a/Lib/csharp/std_string.i
+++ b/Lib/csharp/std_string.i
@@ -20,7 +20,7 @@ namespace std {
class string;
// string
-%typemap(ctype) string "char *"
+%typemap(ctype) string "const char *"
%typemap(imtype) string "string"
%typemap(cstype) string "string"
@@ -42,7 +42,7 @@ class string;
}
$result.assign($input); %}
-%typemap(directorin) string %{ $input = SWIG_csharp_string_callback($1.c_str()); %}
+%typemap(directorin) string %{ $input = $1.c_str(); %}
%typemap(csin) string "$csinput"
%typemap(csout, excode=SWIGEXCODE) string {
@@ -57,7 +57,7 @@ class string;
return $null; %}
// const string &
-%typemap(ctype) const string & "char *"
+%typemap(ctype) const string & "const char *"
%typemap(imtype) const string & "string"
%typemap(cstype) const string & "string"
@@ -89,7 +89,7 @@ class string;
$1_str = $input;
$result = &$1_str; %}
-%typemap(directorin) const string & %{ $input = SWIG_csharp_string_callback($1.c_str()); %}
+%typemap(directorin) const string & %{ $input = $1.c_str(); %}
%typemap(csvarin, excode=SWIGEXCODE2) const string & %{
set {
diff --git a/Lib/csharp/std_string_view.i b/Lib/csharp/std_string_view.i
new file mode 100644
index 000000000..3b6cd40ef
--- /dev/null
+++ b/Lib/csharp/std_string_view.i
@@ -0,0 +1,116 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * Typemaps for std::string_view and const std::string_view&
+ * These are mapped to a C# String and are passed around by value.
+ *
+ * To use non-const std::string_view references use the following %apply. Note
+ * that they are passed by value.
+ * %apply const std::string_view & {std::string_view &};
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <string_view>
+#include <string>
+%}
+
+namespace std {
+
+%naturalvar string_view;
+
+class string_view;
+
+// string_view
+%typemap(ctype) string_view "const char *"
+%typemap(imtype) string_view "string"
+%typemap(cstype) string_view "string"
+
+%typemap(csdirectorin) string_view "$iminput"
+%typemap(csdirectorout) string_view "$cscall"
+
+%typemap(in, canthrow=1) string_view
+%{ if (!$input) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return $null;
+ }
+ $1 = std::string_view($input); %}
+%typemap(out) string_view %{ $result = SWIG_csharp_string_callback(std::string($1).c_str()); %}
+
+%typemap(directorout, canthrow=1, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) string_view
+%{ if (!$input) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return $null;
+ }
+ /* possible thread/reentrant code problem */
+ static std::string $1_str;
+ $1_str = $input;
+ $result = std::string_view($1_str); %}
+
+%typemap(directorin) string_view %{ $input = std::string($1).c_str(); %}
+
+%typemap(csin) string_view "$csinput"
+%typemap(csout, excode=SWIGEXCODE) string_view {
+ string ret = $imcall;$excode
+ return ret;
+ }
+
+%typemap(typecheck) string_view = char *;
+
+%typemap(throws, canthrow=1) string_view
+%{ SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, std::string($1).c_str());
+ return $null; %}
+
+// const string_view &
+%typemap(ctype) const string_view & "const char *"
+%typemap(imtype) const string_view & "string"
+%typemap(cstype) const string_view & "string"
+
+%typemap(csdirectorin) const string_view & "$iminput"
+%typemap(csdirectorout) const string_view & "$cscall"
+
+%typemap(in, canthrow=1) const string_view &
+%{ if (!$input) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return $null;
+ }
+ $*1_ltype $1_str($input);
+ $1 = &$1_str; %}
+%typemap(out) const string_view & %{ $result = SWIG_csharp_string_callback(std::string(*$1).c_str()); %}
+
+%typemap(csin) const string_view & "$csinput"
+%typemap(csout, excode=SWIGEXCODE) const string_view & {
+ string ret = $imcall;$excode
+ return ret;
+ }
+
+%typemap(directorout, canthrow=1, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string_view &
+%{ if (!$input) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return $null;
+ }
+ /* possible thread/reentrant code problem */
+ static std::string $1_str;
+ $1_str = $input;
+ static $*1_ltype $1_strview;
+ $1_strview = $1_str;
+ $result = &$1_strview; %}
+
+%typemap(directorin) const string_view & %{ $input = std::string($1).c_str(); %}
+
+%typemap(csvarin, excode=SWIGEXCODE2) const string_view & %{
+ set {
+ $imcall;$excode
+ } %}
+%typemap(csvarout, excode=SWIGEXCODE2) const string_view & %{
+ get {
+ string ret = $imcall;$excode
+ return ret;
+ } %}
+
+%typemap(typecheck) const string_view & = char *;
+
+%typemap(throws, canthrow=1) const string_view &
+%{ SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, std::string($1).c_str());
+ return $null; %}
+
+}
diff --git a/Lib/csharp/std_unique_ptr.i b/Lib/csharp/std_unique_ptr.i
new file mode 100644
index 000000000..0a4caafbc
--- /dev/null
+++ b/Lib/csharp/std_unique_ptr.i
@@ -0,0 +1,38 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (ctype) std::unique_ptr< TYPE > "void *"
+%typemap (imtype, out="System.IntPtr") std::unique_ptr< TYPE > "global::System.Runtime.InteropServices.HandleRef"
+%typemap (cstype) std::unique_ptr< TYPE > "$typemap(cstype, TYPE)"
+
+%typemap(in) std::unique_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(csin) std::unique_ptr< TYPE > "$typemap(cstype, TYPE).swigRelease($csinput)"
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ $result = (void *)$1.release();
+%}
+
+%typemap(csout, excode=SWIGEXCODE) std::unique_ptr< TYPE > {
+ System.IntPtr cPtr = $imcall;
+ $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
+ return ret;
+ }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::unique_ptr< TYPE > ""
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/csharp/std_unordered_map.i b/Lib/csharp/std_unordered_map.i
new file mode 100644
index 000000000..f8145e372
--- /dev/null
+++ b/Lib/csharp/std_unordered_map.i
@@ -0,0 +1,306 @@
+/* -----------------------------------------------------------------------------
+ * std_unordered_map.i
+ *
+ * SWIG typemaps for std::unordered_map< K, T, H >
+ *
+ * The C# wrapper is made to look and feel like a C# System.Collections.Generic.IDictionary<>.
+ *
+ * Using this wrapper is fairly simple. For example, to create an unordered_map from integers to doubles use:
+ *
+ * %include <std_unordered_map.i>
+ * %template(MapIntDouble) std::unordered_map<int, double>
+ *
+ * Notes:
+ * 1) IEnumerable<> is implemented in the proxy class which is useful for using LINQ with
+ * C++ std::unordered_map wrappers.
+ *
+ * Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents!
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <unordered_map>
+#include <algorithm>
+#include <stdexcept>
+%}
+
+/* K is the C++ key type, T is the C++ value type */
+%define SWIG_STD_UNORDERED_MAP_INTERNAL(K, T, H)
+
+%typemap(csinterfaces) std::unordered_map< K, T, H > "global::System.IDisposable \n , global::System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n"
+%proxycode %{
+
+ public $typemap(cstype, T) this[$typemap(cstype, K) key] {
+ get {
+ return getitem(key);
+ }
+
+ set {
+ setitem(key, value);
+ }
+ }
+
+ public bool TryGetValue($typemap(cstype, K) key, out $typemap(cstype, T) value) {
+ if (this.ContainsKey(key)) {
+ value = this[key];
+ return true;
+ }
+ value = default($typemap(cstype, T));
+ return false;
+ }
+
+ public bool IsEmpty {
+ get {
+ return empty();
+ }
+ }
+
+ public int Count {
+ get {
+ return (int)size();
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public global::System.Collections.Generic.ICollection<$typemap(cstype, K)> Keys {
+ get {
+ global::System.Collections.Generic.ICollection<$typemap(cstype, K)> keys = new global::System.Collections.Generic.List<$typemap(cstype, K)>();
+ int size = this.Count;
+ if (size > 0) {
+ global::System.IntPtr iter = create_iterator_begin();
+ for (int i = 0; i < size; i++) {
+ keys.Add(get_next_key(iter));
+ }
+ destroy_iterator(iter);
+ }
+ return keys;
+ }
+ }
+
+ public global::System.Collections.Generic.ICollection<$typemap(cstype, T)> Values {
+ get {
+ global::System.Collections.Generic.ICollection<$typemap(cstype, T)> vals = new global::System.Collections.Generic.List<$typemap(cstype, T)>();
+ foreach (global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> pair in this) {
+ vals.Add(pair.Value);
+ }
+ return vals;
+ }
+ }
+
+ public void Add(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
+ Add(item.Key, item.Value);
+ }
+
+ public bool Remove(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
+ if (Contains(item)) {
+ return Remove(item.Key);
+ } else {
+ return false;
+ }
+ }
+
+ public bool Contains(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
+ if (this[item.Key] == item.Value) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void CopyTo(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>[] array) {
+ CopyTo(array, 0);
+ }
+
+ public void CopyTo(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>[] array, int arrayIndex) {
+ if (array == null)
+ throw new global::System.ArgumentNullException("array");
+ if (arrayIndex < 0)
+ throw new global::System.ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
+ if (array.Rank > 1)
+ throw new global::System.ArgumentException("Multi dimensional array.", "array");
+ if (arrayIndex+this.Count > array.Length)
+ throw new global::System.ArgumentException("Number of elements to copy is too large.");
+
+ global::System.Collections.Generic.IList<$typemap(cstype, K)> keyList = new global::System.Collections.Generic.List<$typemap(cstype, K)>(this.Keys);
+ for (int i = 0; i < keyList.Count; i++) {
+ $typemap(cstype, K) currentKey = keyList[i];
+ array.SetValue(new global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>(currentKey, this[currentKey]), arrayIndex+i);
+ }
+ }
+
+ global::System.Collections.Generic.IEnumerator<global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>> global::System.Collections.Generic.IEnumerable<global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>>.GetEnumerator() {
+ return new $csclassnameEnumerator(this);
+ }
+
+ global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() {
+ return new $csclassnameEnumerator(this);
+ }
+
+ public $csclassnameEnumerator GetEnumerator() {
+ return new $csclassnameEnumerator(this);
+ }
+
+ // Type-safe enumerator
+ /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
+ /// whenever the collection is modified. This has been done for changes in the size of the
+ /// collection but not when one of the elements of the collection is modified as it is a bit
+ /// tricky to detect unmanaged code that modifies the collection under our feet.
+ public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator,
+ global::System.Collections.Generic.IEnumerator<global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>>
+ {
+ private $csclassname collectionRef;
+ private global::System.Collections.Generic.IList<$typemap(cstype, K)> keyCollection;
+ private int currentIndex;
+ private object currentObject;
+ private int currentSize;
+
+ public $csclassnameEnumerator($csclassname collection) {
+ collectionRef = collection;
+ keyCollection = new global::System.Collections.Generic.List<$typemap(cstype, K)>(collection.Keys);
+ currentIndex = -1;
+ currentObject = null;
+ currentSize = collectionRef.Count;
+ }
+
+ // Type-safe iterator Current
+ public global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> Current {
+ get {
+ if (currentIndex == -1)
+ throw new global::System.InvalidOperationException("Enumeration not started.");
+ if (currentIndex > currentSize - 1)
+ throw new global::System.InvalidOperationException("Enumeration finished.");
+ if (currentObject == null)
+ throw new global::System.InvalidOperationException("Collection modified.");
+ return (global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>)currentObject;
+ }
+ }
+
+ // Type-unsafe IEnumerator.Current
+ object global::System.Collections.IEnumerator.Current {
+ get {
+ return Current;
+ }
+ }
+
+ public bool MoveNext() {
+ int size = collectionRef.Count;
+ bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
+ if (moveOkay) {
+ currentIndex++;
+ $typemap(cstype, K) currentKey = keyCollection[currentIndex];
+ currentObject = new global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>(currentKey, collectionRef[currentKey]);
+ } else {
+ currentObject = null;
+ }
+ return moveOkay;
+ }
+
+ public void Reset() {
+ currentIndex = -1;
+ currentObject = null;
+ if (collectionRef.Count != currentSize) {
+ throw new global::System.InvalidOperationException("Collection modified.");
+ }
+ }
+
+ public void Dispose() {
+ currentIndex = -1;
+ currentObject = null;
+ }
+ }
+
+%}
+
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef K key_type;
+ typedef T mapped_type;
+ typedef std::pair< const K, T > value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ unordered_map();
+ unordered_map(const unordered_map& other);
+ size_type size() const;
+ bool empty() const;
+ %rename(Clear) clear;
+ void clear();
+ %extend {
+ const mapped_type& getitem(const key_type& key) throw (std::out_of_range) {
+ std::unordered_map< K, T, H >::iterator iter = $self->find(key);
+ if (iter != $self->end())
+ return iter->second;
+ else
+ throw std::out_of_range("key not found");
+ }
+
+ void setitem(const key_type& key, const mapped_type& x) {
+ (*$self)[key] = x;
+ }
+
+ bool ContainsKey(const key_type& key) {
+ std::unordered_map< K, T, H >::iterator iter = $self->find(key);
+ return iter != $self->end();
+ }
+
+ void Add(const key_type& key, const mapped_type& value) throw (std::out_of_range) {
+ std::unordered_map< K, T, H >::iterator iter = $self->find(key);
+ if (iter != $self->end())
+ throw std::out_of_range("key already exists");
+ $self->insert(std::pair< K, T >(key, value));
+ }
+
+ bool Remove(const key_type& key) {
+ std::unordered_map< K, T, H >::iterator iter = $self->find(key);
+ if (iter != $self->end()) {
+ $self->erase(iter);
+ return true;
+ }
+ return false;
+ }
+
+ // create_iterator_begin(), get_next_key() and destroy_iterator work together to provide a collection of keys to C#
+ %apply void *VOID_INT_PTR { std::unordered_map< K, T, H >::iterator *create_iterator_begin }
+ %apply void *VOID_INT_PTR { std::unordered_map< K, T, H >::iterator *swigiterator }
+
+ std::unordered_map< K, T, H >::iterator *create_iterator_begin() {
+ return new std::unordered_map< K, T, H >::iterator($self->begin());
+ }
+
+ const key_type& get_next_key(std::unordered_map< K, T, H >::iterator *swigiterator) {
+ (void)self;
+ std::unordered_map< K, T, H >::iterator iter = *swigiterator;
+ (*swigiterator)++;
+ return (*iter).first;
+ }
+
+ void destroy_iterator(std::unordered_map< K, T, H >::iterator *swigiterator) {
+ (void)self;
+ delete swigiterator;
+ }
+ }
+
+
+%enddef
+
+%csmethodmodifiers std::unordered_map::empty "private"
+%csmethodmodifiers std::unordered_map::size "private"
+%csmethodmodifiers std::unordered_map::getitem "private"
+%csmethodmodifiers std::unordered_map::setitem "private"
+%csmethodmodifiers std::unordered_map::create_iterator_begin "private"
+%csmethodmodifiers std::unordered_map::get_next_key "private"
+%csmethodmodifiers std::unordered_map::destroy_iterator "private"
+
+// Default implementation
+namespace std {
+ template<class K, class T, class H = std::hash<K> > class unordered_map {
+ SWIG_STD_UNORDERED_MAP_INTERNAL(K, T, H)
+ };
+}
diff --git a/Lib/csharp/std_unordered_set.i b/Lib/csharp/std_unordered_set.i
new file mode 100644
index 000000000..d6f6a18f3
--- /dev/null
+++ b/Lib/csharp/std_unordered_set.i
@@ -0,0 +1,320 @@
+/* -----------------------------------------------------------------------------
+ * std_unordered_set.i
+ *
+ * SWIG typemaps for std::unordered_set<T>.
+ *
+ * Note that ISet<> used here requires .NET 4 or later.
+ *
+ * The C# wrapper implements ISet<> interface and is similar in
+ * characteristics to the C# System.Collections.Generic.HashSet<> class, but
+ * doesn't provide quite all of its methods.
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <unordered_set>
+#include <algorithm>
+#include <stdexcept>
+%}
+
+%csmethodmodifiers std::unordered_set::empty "private"
+%csmethodmodifiers std::unordered_set::size "private"
+%csmethodmodifiers std::unordered_set::getitem "private"
+%csmethodmodifiers std::unordered_set::create_iterator_begin "private"
+%csmethodmodifiers std::unordered_set::get_next "private"
+%csmethodmodifiers std::unordered_set::destroy_iterator "private"
+
+namespace std {
+
+// TODO: Add support for comparator and allocator template parameters.
+template <class T>
+class unordered_set {
+
+%typemap(csinterfaces) std::unordered_set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n"
+%proxycode %{
+ void global::System.Collections.Generic.ICollection<$typemap(cstype, T)>.Add($typemap(cstype, T) item) {
+ ((global::System.Collections.Generic.ISet<$typemap(cstype, T)>)this).Add(item);
+ }
+
+ public bool TryGetValue($typemap(cstype, T) equalValue, out $typemap(cstype, T) actualValue) {
+ try {
+ actualValue = getitem(equalValue);
+ return true;
+ } catch {
+ actualValue = default($typemap(cstype, T));
+ return false;
+ }
+ }
+
+ public bool IsEmpty {
+ get {
+ return empty();
+ }
+ }
+
+ public int Count {
+ get {
+ return (int)size();
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public void CopyTo($typemap(cstype, T)[] array) {
+ CopyTo(array, 0);
+ }
+
+ public void CopyTo($typemap(cstype, T)[] array, int arrayIndex) {
+ if (array == null)
+ throw new global::System.ArgumentNullException("array");
+ if (arrayIndex < 0)
+ throw new global::System.ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
+ if (array.Rank > 1)
+ throw new global::System.ArgumentException("Multi dimensional array.", "array");
+ if (arrayIndex+this.Count > array.Length)
+ throw new global::System.ArgumentException("Number of elements to copy is too large.");
+
+ foreach ($typemap(cstype, T) item in this) {
+ array.SetValue(item, arrayIndex++);
+ }
+ }
+
+ public void ExceptWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ foreach ($typemap(cstype, T) item in other) {
+ Remove(item);
+ }
+ }
+
+ public void IntersectWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ $csclassname old = new $csclassname(this);
+
+ Clear();
+ foreach ($typemap(cstype, T) item in other) {
+ if (old.Contains(item))
+ Add(item);
+ }
+ }
+
+ private static int count_enum(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ int count = 0;
+ foreach ($typemap(cstype, T) item in other) {
+ count++;
+ }
+
+ return count;
+ }
+
+ public bool IsProperSubsetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ return IsSubsetOf(other) && Count < count_enum(other);
+ }
+
+ public bool IsProperSupersetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ return IsSupersetOf(other) && Count > count_enum(other);
+ }
+
+ public bool IsSubsetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ int countContained = 0;
+
+ foreach ($typemap(cstype, T) item in other) {
+ if (Contains(item))
+ countContained++;
+ }
+
+ return countContained == Count;
+ }
+
+ public bool IsSupersetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ foreach ($typemap(cstype, T) item in other) {
+ if (!Contains(item))
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool Overlaps(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ foreach ($typemap(cstype, T) item in other) {
+ if (Contains(item))
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool SetEquals(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ return IsSupersetOf(other) && Count == count_enum(other);
+ }
+
+ public void SymmetricExceptWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ foreach ($typemap(cstype, T) item in other) {
+ if (!Remove(item))
+ Add(item);
+ }
+ }
+
+ public void UnionWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+ foreach ($typemap(cstype, T) item in other) {
+ Add(item);
+ }
+ }
+
+ private global::System.Collections.Generic.ICollection<$typemap(cstype, T)> Items {
+ get {
+ global::System.Collections.Generic.ICollection<$typemap(cstype, T)> items = new global::System.Collections.Generic.List<$typemap(cstype, T)>();
+ int size = this.Count;
+ if (size > 0) {
+ global::System.IntPtr iter = create_iterator_begin();
+ for (int i = 0; i < size; i++) {
+ items.Add(get_next(iter));
+ }
+ destroy_iterator(iter);
+ }
+ return items;
+ }
+ }
+
+ global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>.GetEnumerator() {
+ return new $csclassnameEnumerator(this);
+ }
+
+ global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() {
+ return new $csclassnameEnumerator(this);
+ }
+
+ public $csclassnameEnumerator GetEnumerator() {
+ return new $csclassnameEnumerator(this);
+ }
+
+ // Type-safe enumerator
+ /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
+ /// whenever the collection is modified. This has been done for changes in the size of the
+ /// collection but not when one of the elements of the collection is modified as it is a bit
+ /// tricky to detect unmanaged code that modifies the collection under our feet.
+ public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator,
+ global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)>
+ {
+ private $csclassname collectionRef;
+ private global::System.Collections.Generic.IList<$typemap(cstype, T)> ItemsCollection;
+ private int currentIndex;
+ private object currentObject;
+ private int currentSize;
+
+ public $csclassnameEnumerator($csclassname collection) {
+ collectionRef = collection;
+ ItemsCollection = new global::System.Collections.Generic.List<$typemap(cstype, T)>(collection.Items);
+ currentIndex = -1;
+ currentObject = null;
+ currentSize = collectionRef.Count;
+ }
+
+ // Type-safe iterator Current
+ public $typemap(cstype, T) Current {
+ get {
+ if (currentIndex == -1)
+ throw new global::System.InvalidOperationException("Enumeration not started.");
+ if (currentIndex > currentSize - 1)
+ throw new global::System.InvalidOperationException("Enumeration finished.");
+ if (currentObject == null)
+ throw new global::System.InvalidOperationException("Collection modified.");
+ return ($typemap(cstype, T))currentObject;
+ }
+ }
+
+ // Type-unsafe IEnumerator.Current
+ object global::System.Collections.IEnumerator.Current {
+ get {
+ return Current;
+ }
+ }
+
+ public bool MoveNext() {
+ int size = collectionRef.Count;
+ bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
+ if (moveOkay) {
+ currentIndex++;
+ currentObject = ItemsCollection[currentIndex];
+ } else {
+ currentObject = null;
+ }
+ return moveOkay;
+ }
+
+ public void Reset() {
+ currentIndex = -1;
+ currentObject = null;
+ if (collectionRef.Count != currentSize) {
+ throw new global::System.InvalidOperationException("Collection modified.");
+ }
+ }
+
+ public void Dispose() {
+ currentIndex = -1;
+ currentObject = null;
+ }
+ }
+
+%}
+
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T key_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ unordered_set();
+ unordered_set(const unordered_set& other);
+ size_type size() const;
+ bool empty() const;
+ %rename(Clear) clear;
+ void clear();
+ %extend {
+ bool Add(const value_type& item) {
+ return $self->insert(item).second;
+ }
+
+ bool Contains(const value_type& item) {
+ return $self->count(item) != 0;
+ }
+
+ bool Remove(const value_type& item) {
+ return $self->erase(item) != 0;
+ }
+
+ const value_type& getitem(const value_type& item) throw (std::out_of_range) {
+ std::unordered_set<T>::iterator iter = $self->find(item);
+ if (iter == $self->end())
+ throw std::out_of_range("item not found");
+
+ return *iter;
+ }
+
+ // create_iterator_begin(), get_next() and destroy_iterator work together to provide a collection of items to C#
+ %apply void *VOID_INT_PTR { std::unordered_set<T>::iterator *create_iterator_begin }
+ %apply void *VOID_INT_PTR { std::unordered_set<T>::iterator *swigiterator }
+
+ std::unordered_set<T>::iterator *create_iterator_begin() {
+ return new std::unordered_set<T>::iterator($self->begin());
+ }
+
+ const key_type& get_next(std::unordered_set<T>::iterator *swigiterator) {
+ (void)$self;
+ std::unordered_set<T>::iterator iter = *swigiterator;
+ (*swigiterator)++;
+ return *iter;
+ }
+
+ void destroy_iterator(std::unordered_set<T>::iterator *swigiterator) {
+ (void)$self;
+ delete swigiterator;
+ }
+ }
+};
+
+}
diff --git a/Lib/csharp/std_vector.i b/Lib/csharp/std_vector.i
index e2811290c..982306e0d 100644
--- a/Lib/csharp/std_vector.i
+++ b/Lib/csharp/std_vector.i
@@ -19,7 +19,7 @@
// MACRO for use within the std::vector class body
%define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CSINTERFACE, CONST_REFERENCE, CTYPE...)
-%typemap(csinterfaces) std::vector< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n";
+%typemap(csinterfaces) std::vector< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n"
%proxycode %{
public $csclassname(global::System.Collections.IEnumerable c) : this() {
if (c == null)
@@ -63,12 +63,18 @@
return (int)capacity();
}
set {
- if (value < size())
+ if (value < 0 || ($typemap(cstype, size_t))value < size())
throw new global::System.ArgumentOutOfRangeException("Capacity");
reserve(($typemap(cstype, size_t))value);
}
}
+ public bool IsEmpty {
+ get {
+ return empty();
+ }
+ }
+
public int Count {
get {
return (int)size();
@@ -203,19 +209,20 @@
typedef value_type& reference;
typedef CONST_REFERENCE const_reference;
+ vector();
+ vector(const vector &other);
+
%rename(Clear) clear;
void clear();
%rename(Add) push_back;
void push_back(CTYPE const& x);
size_type size() const;
+ bool empty() const;
size_type capacity() const;
void reserve(size_type n);
%newobject GetRange(int index, int count);
%newobject Repeat(CTYPE const& value, int count);
- vector();
- vector(const vector &other);
-
%extend {
vector(int capacity) throw (std::out_of_range) {
std::vector< CTYPE >* pv = 0;
@@ -357,22 +364,13 @@ namespace std {
}
%enddef
-// Legacy macros
-%define SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE...)
-#warning SWIG_STD_VECTOR_SPECIALIZE macro deprecated, please see csharp/std_vector.i and switch to SWIG_STD_VECTOR_ENHANCED
-SWIG_STD_VECTOR_ENHANCED(CTYPE)
-%enddef
-
-%define SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE...)
-#warning SWIG_STD_VECTOR_SPECIALIZE_MINIMUM macro deprecated, it is no longer required
-%enddef
-
%{
#include <vector>
#include <algorithm>
#include <stdexcept>
%}
+%csmethodmodifiers std::vector::empty "private"
%csmethodmodifiers std::vector::getitemcopy "private"
%csmethodmodifiers std::vector::getitem "private"
%csmethodmodifiers std::vector::setitem "private"
@@ -415,4 +413,3 @@ SWIG_STD_VECTOR_ENHANCED(float)
SWIG_STD_VECTOR_ENHANCED(double)
SWIG_STD_VECTOR_ENHANCED(std::string) // also requires a %include <std_string.i>
SWIG_STD_VECTOR_ENHANCED(std::wstring) // also requires a %include <std_wstring.i>
-
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i
index 162b90e80..c7fef41a5 100644
--- a/Lib/csharp/std_wstring.i
+++ b/Lib/csharp/std_wstring.i
@@ -2,7 +2,9 @@
* std_wstring.i
*
* Typemaps for std::wstring and const std::wstring&
- * These are mapped to a C# String and are passed around by value.
+ * std::wstring is mapped to a C# Unicode string (UTF16) and is passed around by value.
+ * std::wstring support includes wchar_t as a 2 byte type (Windows) and a 4 byte type
+ * (most Unix systems).
*
* To use non-const std::wstring references use the following %apply. Note
* that they are passed by value.
@@ -15,6 +17,28 @@
#include <string>
%}
+%fragment("Swig_csharp_UTF16ToWString", "header") %{
+/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
+static std::wstring Swig_csharp_UTF16ToWString(const unsigned short *str) {
+ if (sizeof(wchar_t) == 2) {
+ return std::wstring((wchar_t *)str);
+ } else {
+ const unsigned short *pBegin(str);
+ const unsigned short *ptr(pBegin);
+
+ while (*ptr != 0)
+ ++ptr;
+
+ std::wstring result;
+ result.reserve(ptr - pBegin);
+ while(pBegin != ptr)
+ result.push_back(*pBegin++);
+
+ return result;
+ }
+}
+%}
+
namespace std {
%naturalvar wstring;
@@ -22,31 +46,33 @@ namespace std {
class wstring;
// wstring
-%typemap(ctype, out="void *") wstring "wchar_t *"
+%typemap(ctype, out="void *") wstring "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) wstring "string"
%typemap(cstype) wstring "string"
%typemap(csdirectorin) wstring "$iminput"
%typemap(csdirectorout) wstring "$cscall"
-%typemap(in, canthrow=1) wstring
+%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") wstring
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- $1.assign($input); %}
-%typemap(out) wstring %{ $result = SWIG_csharp_wstring_callback($1.c_str()); %}
+ $1 = Swig_csharp_UTF16ToWString($input); %}
+%typemap(out) wstring %{ $result = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %}
-%typemap(directorout, canthrow=1) wstring
+%typemap(directorout, canthrow=1) wstring
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- $result.assign($input); %}
+ $result = Swig_csharp_UTF16ToWString($input); %}
-%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %}
+%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %}
%typemap(csin) wstring "$csinput"
%typemap(csout, excode=SWIGEXCODE) wstring {
@@ -57,29 +83,30 @@ class wstring;
%typemap(typecheck) wstring = wchar_t *;
%typemap(throws, canthrow=1) wstring
-%{ std::string message($1.begin(), $1.end());
- SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str());
+%{ SWIG_csharp_ApplicationException_callback($1.data(), (int)$1.size());
return $null; %}
// const wstring &
-%typemap(ctype, out="void *") const wstring & "wchar_t *"
+%typemap(ctype, out="void *") const wstring & "unsigned short *"
%typemap(imtype,
inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
- outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
) const wstring & "string"
%typemap(cstype) const wstring & "string"
%typemap(csdirectorin) const wstring & "$iminput"
%typemap(csdirectorout) const wstring & "$cscall"
-%typemap(in, canthrow=1) const wstring &
+%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") const wstring &
%{ if (!$input) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
return $null;
}
- std::wstring $1_str($input);
+ std::wstring $1_str(Swig_csharp_UTF16ToWString($input));
$1 = &$1_str; %}
-%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_callback($1->c_str()); %}
+%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_with_length_callback($1->data(), (int)$1->size()); %}
%typemap(csin) const wstring & "$csinput"
%typemap(csout, excode=SWIGEXCODE) const wstring & {
@@ -94,10 +121,10 @@ class wstring;
}
/* possible thread/reentrant code problem */
static std::wstring $1_str;
- $1_str = $input;
+ $1_str = Swig_csharp_UTF16ToWString($input);
$result = &$1_str; %}
-%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %}
+%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %}
%typemap(csvarin, excode=SWIGEXCODE2) const wstring & %{
set {
@@ -112,8 +139,7 @@ class wstring;
%typemap(typecheck) const wstring & = wchar_t *;
%typemap(throws, canthrow=1) const wstring &
-%{ std::string message($1.begin(), $1.end());
- SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str());
+%{ SWIG_csharp_ApplicationException_callback($1.data(), (int)$1.size());
return $null; %}
}
diff --git a/Lib/csharp/swigmove.i b/Lib/csharp/swigmove.i
new file mode 100644
index 000000000..2f21bd6f7
--- /dev/null
+++ b/Lib/csharp/swigmove.i
@@ -0,0 +1,16 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, canthrow=1, fragment="<memory>") SWIGTYPE MOVE ($&1_type argp)
+%{ argp = ($&1_ltype)$input;
+ if (!argp) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null $1_type", 0);
+ return $null;
+ }
+ SwigValueWrapper< $1_ltype >::reset($1, argp); %}
+
+%typemap(csin) SWIGTYPE MOVE "$&csclassname.swigRelease($csinput)"
diff --git a/Lib/csharp/typemaps.i b/Lib/csharp/typemaps.i
index b6f9bddbd..80a5cb545 100644
--- a/Lib/csharp/typemaps.i
+++ b/Lib/csharp/typemaps.i
@@ -74,15 +74,11 @@ INPUT_TYPEMAP(short, short, short)
INPUT_TYPEMAP(unsigned short, unsigned short, ushort)
INPUT_TYPEMAP(int, int, int)
INPUT_TYPEMAP(unsigned int, unsigned int, uint)
-INPUT_TYPEMAP(long, long, int)
-INPUT_TYPEMAP(unsigned long, unsigned long, uint)
INPUT_TYPEMAP(long long, long long, long)
INPUT_TYPEMAP(unsigned long long, unsigned long long, ulong)
INPUT_TYPEMAP(float, float, float)
INPUT_TYPEMAP(double, double, double)
-#undef INPUT_TYPEMAP
-
/*
OUTPUT typemaps
---------------
@@ -153,15 +149,11 @@ OUTPUT_TYPEMAP(short, short, short, INT16_PTR)
OUTPUT_TYPEMAP(unsigned short, unsigned short, ushort, UINT16_PTR)
OUTPUT_TYPEMAP(int, int, int, INT32_PTR)
OUTPUT_TYPEMAP(unsigned int, unsigned int, uint, UINT32_PTR)
-OUTPUT_TYPEMAP(long, long, int, INT32_PTR)
-OUTPUT_TYPEMAP(unsigned long, unsigned long, uint, UINT32_PTR)
OUTPUT_TYPEMAP(long long, long long, long, INT64_PTR)
OUTPUT_TYPEMAP(unsigned long long, unsigned long long, ulong, UINT64_PTR)
OUTPUT_TYPEMAP(float, float, float, FLOAT_PTR)
OUTPUT_TYPEMAP(double, double, double, DOUBLE_PTR)
-#undef OUTPUT_TYPEMAP
-
%typemap(in) bool *OUTPUT, bool &OUTPUT
%{ *$input = 0;
$1 = ($1_ltype)$input; %}
@@ -242,12 +234,47 @@ INOUT_TYPEMAP(short, short, short, INT16_PTR)
INOUT_TYPEMAP(unsigned short, unsigned short, ushort, UINT16_PTR)
INOUT_TYPEMAP(int, int, int, INT32_PTR)
INOUT_TYPEMAP(unsigned int, unsigned int, uint, UINT32_PTR)
-INOUT_TYPEMAP(long, long, int, INT32_PTR)
-INOUT_TYPEMAP(unsigned long, unsigned long, uint, UINT32_PTR)
INOUT_TYPEMAP(long long, long long, long, INT64_PTR)
INOUT_TYPEMAP(unsigned long long, unsigned long long, ulong, UINT64_PTR)
INOUT_TYPEMAP(float, float, float, FLOAT_PTR)
INOUT_TYPEMAP(double, double, double, DOUBLE_PTR)
-#undef INOUT_TYPEMAP
+// 32-bit/64-bit architecture specific typemaps - marshal as 32-bit by default
+#if !defined(SWIGWORDSIZE64)
+INPUT_TYPEMAP(long, int, int)
+INPUT_TYPEMAP(unsigned long, unsigned int, uint)
+
+OUTPUT_TYPEMAP(long, int, int, INT32_PTR)
+OUTPUT_TYPEMAP(unsigned long, unsigned int, uint, UINT32_PTR)
+
+INOUT_TYPEMAP(long, int, int, INT32_PTR)
+INOUT_TYPEMAP(unsigned long, unsigned int, uint, UINT32_PTR)
+#else
+INPUT_TYPEMAP(long, long long, int)
+INPUT_TYPEMAP(unsigned long, unsigned long long, uint)
+
+OUTPUT_TYPEMAP(long, long long, int, INT64_PTR)
+OUTPUT_TYPEMAP(unsigned long, unsigned long long, uint, UINT64_PTR)
+
+INOUT_TYPEMAP(long, long long, int, INT64_PTR)
+INOUT_TYPEMAP(unsigned long, unsigned long long, uint, UINT64_PTR)
+#endif
+%typemap(in) long INPUT[] ($*1_ltype tempinput), unsigned long INPUT[] ($*1_ltype tempinput)
+%{tempinput = ($*1_ltype)*$input;
+ $1 = &tempinput;%}
+
+%typemap(in) long OUTPUT[] ($*1_ltype tempoutput), unsigned long OUTPUT[] ($*1_ltype tempoutput)
+%{$1 = &tempoutput;%}
+
+%typemap(in) long INOUT[] ($*1_ltype tempinout), unsigned long INOUT[] ($*1_ltype tempinout)
+%{tempinout = ($*1_ltype)*$input;
+ $1 = &tempinout;%}
+
+%typemap(argout) long OUTPUT[], unsigned long OUTPUT[] "*$input = *$1;"
+%typemap(argout) long INOUT[], unsigned long INOUT[] "*$input = *$1;"
+
+
+#undef INPUT_TYPEMAP
+#undef OUTPUT_TYPEMAP
+#undef INOUT_TYPEMAP
diff --git a/Lib/csharp/wchar.i b/Lib/csharp/wchar.i
index 798194114..f1e0d5a26 100644
--- a/Lib/csharp/wchar.i
+++ b/Lib/csharp/wchar.i
@@ -2,37 +2,58 @@
* wchar.i
*
* Typemaps for the wchar_t type
- * These are mapped to a C# String and are passed around by value.
+ * wchar_t * is mapped to a C# Unicode string (UTF16) and is passed around by value.
+ * wchar_t * support includes wchar_t as a 2 byte type (Windows) and a 4 byte type
+ * (most Unix systems).
*
* Support code for wide strings can be turned off by defining SWIG_CSHARP_NO_WSTRING_HELPER
- *
* ----------------------------------------------------------------------------- */
#if !defined(SWIG_CSHARP_NO_WSTRING_HELPER)
#if !defined(SWIG_CSHARP_WSTRING_HELPER_)
#define SWIG_CSHARP_WSTRING_HELPER_
+
+%fragment("<wchar.h>"); // TODO: %fragment("<wchar.h", "runtime");
+
%insert(runtime) %{
/* Callback for returning strings to C# without leaking memory */
-typedef void * (SWIGSTDCALL* SWIG_CSharpWStringHelperCallback)(const wchar_t *);
-static SWIG_CSharpWStringHelperCallback SWIG_csharp_wstring_callback = NULL;
+typedef void * (SWIGSTDCALL* SWIG_CSharpWStringHelperCallback)(const wchar_t *, int length);
+static SWIG_CSharpWStringHelperCallback SWIG_csharp_wstring_with_length_callback = NULL;
+%}
+
+%insert(header) %{
+static void * SWIG_csharp_wstring_callback(const wchar_t *s) {
+ return SWIG_csharp_wstring_with_length_callback(s, (int)wcslen(s));
+}
%}
+
%pragma(csharp) imclasscode=%{
protected class SWIGWStringHelper {
[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]
- public delegate string SWIGWStringDelegate(global::System.IntPtr message);
- static SWIGWStringDelegate wstringDelegate = new SWIGWStringDelegate(CreateWString);
+ public delegate string SWIGWStringDelegate(global::System.IntPtr message, int length);
+ static SWIGWStringDelegate wstringUTF16Delegate = new SWIGWStringDelegate(CreateWStringFromUTF16);
+ static SWIGWStringDelegate wstringUTF32Delegate = new SWIGWStringDelegate(CreateWStringFromUTF32);
[global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterWStringCallback_$module")]
- public static extern void SWIGRegisterWStringCallback_$module(SWIGWStringDelegate wstringDelegate);
+ public static extern void SWIGRegisterWStringCallback_$module(SWIGWStringDelegate wstringUTF16Delegate, SWIGWStringDelegate wstringUTF32Delegate);
- static string CreateWString([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString) {
- return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString);
+ public static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString, length);
+ }
+
+ public static string CreateWStringFromUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ if (length == 0)
+ return string.Empty;
+
+ byte[] buffer = new byte[length * 4];
+ global::System.Runtime.InteropServices.Marshal.Copy(cString, buffer, 0, buffer.Length);
+ return global::System.Text.Encoding.UTF32.GetString(buffer);
}
static SWIGWStringHelper() {
- SWIGRegisterWStringCallback_$module(wstringDelegate);
+ SWIGRegisterWStringCallback_$module(wstringUTF16Delegate, wstringUTF32Delegate);
}
}
@@ -43,13 +64,76 @@ static SWIG_CSharpWStringHelperCallback SWIG_csharp_wstring_callback = NULL;
#ifdef __cplusplus
extern "C"
#endif
-SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStringHelperCallback callback) {
- SWIG_csharp_wstring_callback = callback;
+SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStringHelperCallback callback_utf16, SWIG_CSharpWStringHelperCallback callback_utf32) {
+ SWIG_csharp_wstring_with_length_callback = sizeof(wchar_t) == 2 ? callback_utf16 : callback_utf32;
}
%}
#endif // SWIG_CSHARP_WSTRING_HELPER_
#endif // SWIG_CSHARP_NO_WSTRING_HELPER
+#if !defined(SWIG_CSHARP_NO_WSTRING_EXCEPTION_HELPER)
+#if !defined(SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_)
+#define SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_
+
+%insert(runtime) %{
+/* Callback for returning strings to C# without leaking memory */
+typedef void (SWIGSTDCALL* SWIG_CSharpWStringExceptionHelperCallback)(const wchar_t *, int length);
+static SWIG_CSharpWStringExceptionHelperCallback SWIG_csharp_ApplicationException_callback = NULL;
+%}
+
+%pragma(csharp) imclasscode=%{
+ protected class SWIGWStringExceptionHelper {
+
+ [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]
+ public delegate void SWIGWStringExceptionDelegate(global::System.IntPtr message, int length);
+ static SWIGWStringExceptionDelegate applicationExceptionUTF16Delegate = new SWIGWStringExceptionDelegate(SetPendingApplicationExceptionUTF16);
+ static SWIGWStringExceptionDelegate applicationExceptionUTF32Delegate = new SWIGWStringExceptionDelegate(SetPendingApplicationExceptionUTF32);
+
+ [global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterWStringExceptionCallback_$module")]
+ public static extern void SWIGRegisterWStringExceptionCallback_$module(SWIGWStringExceptionDelegate applicationExceptionUTF16Delegate, SWIGWStringExceptionDelegate applicationExceptionUTF32Delegate);
+
+ static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString, length);
+ }
+
+ public static string CreateWStringFromUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ if (length == 0)
+ return string.Empty;
+
+ byte[] buffer = new byte[length * 4];
+ return global::System.Text.Encoding.UTF32.GetString(buffer);
+ }
+
+ static void SetPendingApplicationExceptionUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ string message = SWIGWStringHelper.CreateWStringFromUTF16(cString, length);
+ SWIGPendingException.Set(new global::System.ApplicationException(message, SWIGPendingException.Retrieve()));
+ }
+
+ static void SetPendingApplicationExceptionUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+ string message = SWIGWStringHelper.CreateWStringFromUTF32(cString, length);
+ SWIGPendingException.Set(new global::System.ApplicationException(message, SWIGPendingException.Retrieve()));
+ }
+
+ static SWIGWStringExceptionHelper() {
+ SWIGRegisterWStringExceptionCallback_$module(applicationExceptionUTF16Delegate, applicationExceptionUTF32Delegate);
+ }
+ }
+
+ static protected SWIGWStringExceptionHelper swigWStringExceptionHelper = new SWIGWStringExceptionHelper();
+%}
+
+%insert(runtime) %{
+#ifdef __cplusplus
+extern "C"
+#endif
+SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringExceptionCallback_$module(SWIG_CSharpWStringExceptionHelperCallback callback_utf16, SWIG_CSharpWStringExceptionHelperCallback callback_utf32) {
+ SWIG_csharp_ApplicationException_callback = sizeof(wchar_t) == 2 ? callback_utf16 : callback_utf32;
+}
+%}
+
+#endif // SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_
+#endif // SWIG_CSHARP_NO_WSTRING_EXCEPTION_HELPER
+
// wchar_t
%typemap(ctype) wchar_t "wchar_t"
@@ -77,13 +161,64 @@ SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStri
%typemap(typecheck) wchar_t = char;
// wchar_t *
-%typemap(ctype) wchar_t * "wchar_t *"
-%typemap(imtype, inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", out="global::System.IntPtr" ) wchar_t * "string"
+
+%fragment("Swig_csharp_UTF16ToWCharPtr", "header") %{
+/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
+static wchar_t * Swig_csharp_UTF16ToWCharPtr(const unsigned short *str) {
+ if (sizeof(wchar_t) == 2) {
+ return (wchar_t *)str;
+ } else {
+ wchar_t *result = 0;
+
+ if (str) {
+ const unsigned short *pBegin(str);
+ const unsigned short *pEnd(pBegin);
+ wchar_t *ptr = 0;
+
+ while (*pEnd != 0)
+ ++pEnd;
+
+#ifdef __cplusplus
+ result = ptr = new wchar_t[pEnd - pBegin + 1];
+#else
+ result = ptr = (wchar_t *)malloc(sizeof(wchar_t) * (pEnd - pBegin + 1));
+#endif
+ while(pBegin != pEnd)
+ *ptr++ = *pBegin++;
+ *ptr++ = 0;
+ }
+
+ return result;
+ }
+}
+%}
+
+%fragment("Swig_csharp_UTF16ToWCharPtrFree", "header") %{
+static void Swig_csharp_UTF16ToWCharPtrFree(wchar_t *str) {
+ if (sizeof(wchar_t) != 2) {
+#ifdef __cplusplus
+ delete [] str;
+#else
+ free(str);
+#endif
+ }
+}
+%}
+
+%typemap(ctype, out="void *") wchar_t * "unsigned short *"
+%typemap(imtype,
+ inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+ directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+ ) wchar_t * "string"
%typemap(cstype) wchar_t * "string"
+%typemap(csdirectorin) wchar_t * "$iminput"
+%typemap(csdirectorout) wchar_t * "$cscall"
%typemap(csin) wchar_t * "$csinput"
%typemap(csout, excode=SWIGEXCODE) wchar_t * {
- string ret = global::System.Runtime.InteropServices.Marshal.PtrToStringUni($imcall);$excode
+ string ret = $imcall;$excode
return ret;
}
%typemap(csvarin, excode=SWIGEXCODE2) wchar_t * %{
@@ -96,8 +231,105 @@ SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStri
return ret;
} %}
-%typemap(in) wchar_t * %{ $1 = ($1_ltype)$input; %}
-%typemap(out) wchar_t * %{ $result = (wchar_t *)$1; %}
+%typemap(in, fragment="Swig_csharp_UTF16ToWCharPtr") wchar_t *
+%{ $1 = Swig_csharp_UTF16ToWCharPtr($input); %}
+
+%typemap(out) wchar_t * %{ $result = $1 ? SWIG_csharp_wstring_callback($1) : 0; %}
+
+%typemap(freearg, fragment="Swig_csharp_UTF16ToWCharPtrFree") wchar_t *
+%{ Swig_csharp_UTF16ToWCharPtrFree($1); %}
+
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) wchar_t *
+%{ $result = Swig_csharp_UTF16ToWCharPtr($input); %}
+
+%typemap(directorin) wchar_t * %{ $input = SWIG_csharp_wstring_with_length_callback($1, (int)wcslen($1)); %}
%typemap(typecheck) wchar_t * = char *;
+%typemap(throws, canthrow=1, fragment="<wchar.h>") wchar_t *
+%{ SWIG_csharp_ApplicationException_callback($1, (int)wcslen($1));
+ return $null; %}
+
+
+/* Default typemap for handling wchar_t * members (based on char * in swig.swg) */
+
+#ifdef __cplusplus
+%typemap(memberin,fragment="<wchar.h>") wchar_t * {
+ delete [] $1;
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,fragment="<wchar.h>") wchar_t * {
+ delete [] $1;
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+#else
+%typemap(memberin,fragment="<wchar.h>") wchar_t * {
+ free($1);
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,fragment="<wchar.h>") wchar_t * {
+ free($1);
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+ if ($input && sizeof(wchar_t) == 2) {
+ $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+ wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+ } else {
+ $1 = $input;
+ $input = 0;
+ }
+}
+
+#endif