Permalink
Browse files

Add std_auto_ptr.i defining typemaps for returning std::auto_ptr<>.

These typemaps are currently defined for C#, Java and Python only and the
tests are provided only for these languages.

Also add a brief description of the new header to the documentation.
  • Loading branch information...
1 parent fcd0480 commit f90f645b4959ad6e3b7cf365f41e4ee9ca7ecbf0 @vadz vadz committed Nov 27, 2013
View
@@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.0 (in progress)
============================
+2013-11-27: vadz
+ Add std_auto_ptr.i defining typemaps for returning std::auto_ptr<>.
@wsfulton

wsfulton Nov 30, 2013

Owner

Please prefix this line with: [C#, Java, Python]

+
2013-11-09: wsfulton
[C#] Apply patch #79 from Brant Kyser
- Remove using directives from the generated C# code and fully qualify the use of all .NET
View
@@ -31,6 +31,7 @@
<li><a href="#Library_std_vector">std::vector</a>
<li><a href="#Library_stl_exceptions">STL exceptions</a>
<li><a href="#Library_std_shared_ptr">shared_ptr smart pointer</a>
+<li><a href="#Library_std_auto_ptr">auto_ptr smart pointer</a>
</ul>
<li><a href="#Library_nn16">Utility Libraries</a>
<ul>
@@ -1383,6 +1384,7 @@
<td><b>SWIG Interface library file</b></td>
</tr>
+<tr> <td>std::auto_ptr</td> <td>memory</td> <td>std_auto_ptr.i</td> </tr>
<tr> <td>std::deque</td> <td>deque</td> <td>std_deque.i</td> </tr>
<tr> <td>std::list</td> <td>list</td> <td>std_list.i</td> </tr>
<tr> <td>std::map</td> <td>map</td> <td>std_map.i</td> </tr>
@@ -1874,6 +1876,55 @@
<b>Note:</b> There is currently no support for <tt>%shared_ptr</tt> and the director feature.
+
+<H3><a name="Library_std_auto_ptr"></a>8.4.5 auto_ptr smart pointer</H3>
+
+<p>
+While <tt>std::auto_ptr</tt> is deprecated in C++11, some existing code may
+still be using it, so SWIG provides limited support for this class:
+<tt>std_auto_ptr.i</tt> defines the typemaps which apply to the functions
+returning objects of this type. Any other use of <tt>std_auto_ptr.i</tt> is not
+directly supported.
+</p>
+
+<p>
+A typical example of use would be
+</p>
+<div class="code">
+<pre>
+%include &lt;std_auto_ptr.i&gt;
+
+%auto_ptr(Klass)
+%inline %{
+class Klass {
+public:
+ // Factory function creating objects of this class:
+ static std::auto_ptr&lt;Klass&gt; Create(int value) {
+ return std::auto_ptr&lt;Klass&gt;(new Klass(value));
+ }
+
+ int getValue() const { return m_value; }
+
+private:
+ DerivedIntValue(int value) : m_value(value) {}
+ int m_value;
+};
+%}
+</pre>
+</div>
+
+<p>
+The returned objects can be used naturally from the target language, e.g. from
+C#:
+</p>
+
+<div class="targetlang">
+<pre>
+Klass k = Klass.Create(17);
+int value = k.getValue();
+</pre>
+</div>
+
<H2><a name="Library_nn16"></a>8.5 Utility Libraries</H2>
@@ -246,6 +246,7 @@ CPP_TEST_CASES += \
li_carrays \
li_cdata \
li_cpointer \
+ li_std_auto_ptr \
li_stdint \
li_typemaps \
li_typemaps_apply \
@@ -0,0 +1,37 @@
+using System;
+using li_std_auto_ptrNamespace;
+
+public class li_std_auto_ptr_runme {
+ private static void WaitForGC()
+ {
+ System.GC.Collect();
+ System.GC.WaitForPendingFinalizers();
+ System.Threading.Thread.Sleep(10);
+ }
+
+ public static void Main()
+ {
+ Klass k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
+ if (k1.getLabel() != "first")
+ throw new Exception("wrong object label");
+
+ Klass k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
+ if (Klass.getTotal_count() != 2)
+ throw new Exception("number of objects should be 2");
+
+ k1 = null;
+ WaitForGC();
+
+ if (Klass.getTotal_count() != 1)
+ throw new Exception("number of objects should be 1");
+
+ if (k2.getLabel() != "second")
+ throw new Exception("wrong object label");
+
+ k2 = null;
+ WaitForGC();
+
+ if (Klass.getTotal_count() != 0)
+ throw new Exception("no objects should be left");
+ }
+}
@@ -0,0 +1,48 @@
+import li_std_auto_ptr.*;
+
+public class li_std_auto_ptr_runme {
+ static {
+ try {
+ System.loadLibrary("li_std_auto_ptr");
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+ System.exit(1);
+ }
+ }
+
+ private static void WaitForGC()
+ {
+ System.gc();
+ System.runFinalization();
+ try {
+ java.lang.Thread.sleep(1);
+ } catch (java.lang.InterruptedException e) {
+ }
+ }
+
+ public static void main(String argv[]) throws Throwable
+ {
+ Klass k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
+ if (!k1.getLabel().equals("first"))
+ throw new RuntimeException("wrong object label");
+
+ Klass k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
+ if (Klass.getTotal_count() != 2)
+ throw new RuntimeException("number of objects should be 2");
+
+ k1 = null;
+ WaitForGC();
+
+ if (Klass.getTotal_count() != 1)
+ throw new RuntimeException("number of objects should be 1");
+
+ if (!k2.getLabel().equals("second"))
+ throw new RuntimeException("wrong object label");
+
+ k2 = null;
+ WaitForGC();
+
+ if (Klass.getTotal_count() != 0)
+ throw new RuntimeException("no objects should be left");
+ }
+}
@@ -0,0 +1,56 @@
+%module li_std_auto_ptr
+
+#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON)
+
+%include "std_auto_ptr.i"
+
+%auto_ptr(Klass)
+
+%inline %{
+
+#include <memory>
+#include <string>
+#include "swig_examples_lock.h"
+
+class Klass {
+public:
+ explicit Klass(const char* label) :
+ m_label(label)
+ {
+ SwigExamples::Lock lock(critical_section);
+ total_count++;
+ }
+
+ const char* getLabel() const { return m_label.c_str(); }
+
+ ~Klass()
+ {
+ SwigExamples::Lock lock(critical_section);
+ total_count--;
+ }
+
+ static int getTotal_count() { return total_count; }
+
+private:
+ static SwigExamples::CriticalSection critical_section;
+ static int total_count;
+
+ std::string m_label;
+};
+
+SwigExamples::CriticalSection Klass::critical_section;
+int Klass::total_count = 0;
+
+%}
+
+%template(KlassAutoPtr) std::auto_ptr<Klass>;
+
+%inline %{
+
+std::auto_ptr<Klass> makeKlassAutoPtr(const char* label) {
+ return std::auto_ptr<Klass>(new Klass(label));
+}
+
+%}
+
+#endif
@@ -0,0 +1,17 @@
+from li_std_auto_ptr import *
+
+k1 = makeKlassAutoPtr("first")
+k2 = makeKlassAutoPtr("second")
+if Klass.getTotal_count() != 2:
+ raise "number of objects should be 2"
+
+del k1
+if Klass.getTotal_count() != 1:
+ raise "number of objects should be 1"
+
+if k2.getLabel() != "second":
+ raise "wrong object label"
+
+del k2
+if Klass.getTotal_count() != 0:
+ raise "no objects should be left"
View
@@ -0,0 +1,25 @@
+/*
+ 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).
+ */
+
+%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(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 >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
View
@@ -0,0 +1,27 @@
+/*
+ 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).
+ */
+
+%define %auto_ptr(TYPE)
+%typemap (jni) std::auto_ptr<TYPE > "jlong"
+%typemap (jtype) std::auto_ptr<TYPE > "long"
+%typemap (jstype) std::auto_ptr<TYPE > "$typemap(jstype, TYPE)"
+
+%typemap (out) std::auto_ptr<TYPE > %{
+ jlong lpp = 0;
+ *(TYPE**) &lpp = $1.release();
+ $result = lpp;
+%}
+%typemap(javaout) std::auto_ptr<TYPE > {
+ long cPtr = $jnicall;
+ return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
+ }
+%template() std::auto_ptr<TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
View
@@ -0,0 +1,17 @@
+/*
+ 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).
+ */
+
+%define %auto_ptr(TYPE)
+%typemap (out) std::auto_ptr<TYPE > %{
+ %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+%template() std::auto_ptr<TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}

0 comments on commit f90f645

Please sign in to comment.