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.
This commit is contained in:
Vadim Zeitlin 2013-11-27 15:44:46 +01:00
commit ed28725a15
10 changed files with 282 additions and 0 deletions

View file

@ -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 file

@ -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 @@ The following table shows which C++ classes are supported and the equivalent SWI
<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 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
<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 file

@ -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 file

@ -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 file

@ -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 file

@ -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 file

@ -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"

25
Lib/csharp/std_auto_ptr.i Normal file
View file

@ -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 {};
}

27
Lib/java/std_auto_ptr.i Normal file
View file

@ -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 {};
}

17
Lib/python/std_auto_ptr.i Normal file
View file

@ -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 {};
}