Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

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

Closed
wants to merge 1 commit into from

2 participants

@vadz
Owner

First of all sorry for accidentally pushing this in this repo instead of my own.

Second, this seems to work for me, i.e. the test suite passes for C#, Java, Python and Ruby (which I used as an example of a language for which these typemaps are not implemented), but I do have a couple of questions:

  1. Trivial one: do we need the "li_" prefix? I don't know what is it for but used it for consistency with the existing files.
  2. I'm not sure if the change in Examples/test-suite/common.mk is needed, I don't really understand what's going on there.
  3. Should we have Lib/std_auto_ptr.i used for the other languages too, maybe just giving an #error for them? Currently some parts are duplicated among all three std_auto_ptr.i versions which is not ideal but, again, I did it for consistency with the existing files.
@vadz vadz 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.
f90f645
@wsfulton

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

@wsfulton
Owner

It's a small change, so no big deal putting it in this repo. The implementation is just how I envisaged it should be, so a big +1 for merging to master. Can you do that after addressing the couple of comments I put in against the patch, and then delete the branch afterwards please?

  1. li_ prefix is needed to distinguish the tests from the library that it is testing. The test can't be called std_auto_ptr.i as the library file has the same name. We started off prefixing them lib_, but the dynamic loader on some systems got confused as it treats 'lib' as a special prefix so we changed the prefix.
  2. The common.mk change is needed otherwise the test won't be run by the test-suite.
  3. No. There are lots of library files missing in many languages. A file not found error gets the message across well enough in my opinion, making it easier to diagnose which languages do or don't have support for a particular library by searching for file names.
@vadz vadz closed this
@vadz vadz deleted the auto_ptr branch
@vadz
Owner

I only see one comment which I did address but I managed to mishandle it by forgetting to squash my changes before pushing them, sorry. I'll double triple check my next commits...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 27, 2013
  1. @vadz

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

    vadz authored
    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.
This page is out of date. Refresh to see the latest.
View
3  CHANGES.current
@@ -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<>.
+
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
51 Doc/Manual/Library.html
@@ -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>
View
1  Examples/test-suite/common.mk
@@ -246,6 +246,7 @@ CPP_TEST_CASES += \
li_carrays \
li_cdata \
li_cpointer \
+ li_std_auto_ptr \
li_stdint \
li_typemaps \
li_typemaps_apply \
View
37 Examples/test-suite/csharp/li_std_auto_ptr_runme.cs
@@ -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");
+ }
+}
View
48 Examples/test-suite/java/li_std_auto_ptr_runme.java
@@ -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");
+ }
+}
View
56 Examples/test-suite/li_std_auto_ptr.i
@@ -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
View
17 Examples/test-suite/python/li_std_auto_ptr_runme.py
@@ -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
25 Lib/csharp/std_auto_ptr.i
@@ -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
27 Lib/java/std_auto_ptr.i
@@ -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
17 Lib/python/std_auto_ptr.i
@@ -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 {};
+}
Something went wrong with that request. Please try again.