From 36c2e97a1c4d761fdc89fa374830edea33db95b4 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 1 Jun 2010 19:03:55 +0000 Subject: [PATCH] Add std_shared_ptr.i and document shared_ptr library git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12077 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 10 +++ Doc/Manual/Library.html | 138 ++++++++++++++++++++++++++++++++---- Doc/Manual/SWIGPlus.html | 4 +- Lib/csharp/std_shared_ptr.i | 2 + Lib/java/std_shared_ptr.i | 2 + Lib/python/std_shared_ptr.i | 2 + Lib/shared_ptr.i | 2 + 7 files changed, 143 insertions(+), 17 deletions(-) create mode 100644 Lib/csharp/std_shared_ptr.i create mode 100644 Lib/java/std_shared_ptr.i create mode 100644 Lib/python/std_shared_ptr.i diff --git a/CHANGES.current b/CHANGES.current index c52179d45..a2987e392 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,16 @@ Version 2.0.0 (in progress) ============================ +2010-06-01: wsfulton + Add in std_shared_ptr.i for wrapping std::shared_ptr. Requires the %shared_ptr + macro like in the boost_shared_ptr.i library. std::tr1::shared_ptr can also be + wrapped if the following macro is defined: + + #define SWIG_SHARED_PTR_SUBNAMESPACE tr1 + %include + + shared_ptr is also documented in Library.html now. + 2010-05-27: wsfulton Add the ability for $typemap special variable macros to call other $typemap special variable macros, for example: diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html index c003151ac..8ea8a7a31 100644 --- a/Doc/Manual/Library.html +++ b/Doc/Manual/Library.html @@ -27,8 +27,8 @@
  • STL/C++ Library
  • Utility Libraries @@ -1383,6 +1383,7 @@ The following table shows which C++ classes are supported and the equivalent SWI std::set set std_set.i std::string string std_string.i std::vector vector std_vector.i + std::shared_ptr shared_ptr std_shared_ptr.i @@ -1392,7 +1393,7 @@ Please look for the library files in the appropriate language library directory.

    -

    8.4.1 std_string.i

    +

    std::string

    @@ -1476,16 +1477,11 @@ void foo(string s, const String &t); // std_string typemaps still applie -

    -Note: The std_string library is incompatible with Perl on some platforms. -We're looking into it. -

    - -

    8.4.2 std_vector.i

    +

    std::vector

    -The std_vector.i library provides support for the C++ vector class in the STL. +The std_vector.i library provides support for the C++ std::vector class in the STL. Using this library involves the use of the %template directive. All you need to do is to instantiate different versions of vector for the types that you want to use. For example:

    @@ -1660,11 +1656,6 @@ if you want to make their head explode. details and the public API exposed to the interpreter vary.

    -

    -Note: std_vector.i was written by Luigi "The Amazing" Ballabio. -

    - -

    8.4.3 STL exceptions

    @@ -1715,6 +1706,123 @@ The %exception directive can be used by placing the following code befo Any thrown STL exceptions will then be gracefully handled instead of causing a crash.

    +

    shared_ptr smart pointer

    + +

    +Some target languages have support for handling the widely used boost::shared_ptr smart pointer. +This smart pointer is also available as std::tr1::shared_ptr before it becomes fully standardized as std::shared_ptr. +The boost_shared_ptr.i library provides support for boost::shared_ptr and std_shared_ptr.i provides support for std::shared_ptr, but if the following macro is defined as shown, it can be used for std::tr1::shared_ptr: +

    + +
    +
    +#define SWIG_SHARED_PTR_SUBNAMESPACE tr1
    +%include <std_shared_ptr.i>
    +
    +
    + +

    +You can only use one of these variants of shared_ptr in your interface file at a time. +and all three variants must be used in conjunction with the %shared_ptr(T) macro, +where T is the underlying pointer type equating to usage shared_ptr<T>. +The type T must be non-primitive. +A simple example demonstrates usage: +

    + +
    +
    +%module example
    +%include <boost_shared_ptr.i>
    +%shared_ptr(IntValue)
    +
    +%inline %{
    +#include <boost/shared_ptr.hpp>
    +
    +struct IntValue {
    +  int value;
    +  IntValue(int v) : value(v) {}
    +};
    +
    +static int extractValue(const IntValue &t) {
    +  return t.value;
    +}
    +
    +static int extractValueSmart(boost::shared_ptr<IntValue> t) {
    +  return t->value;
    +}
    +%}
    +
    +
    + +

    +Note that the %shared_ptr(IntValue) declaration occurs after the inclusion of the boost_shared_ptr.i +library which provides the macro and, very importantly, before any usage or declaration of the type, IntValue. +The %shared_ptr macro provides, a few things for handling this smart pointer, but mostly a number of +typemaps. These typemaps override the default typemaps so that the underlying proxy class is stored and passed around +as a pointer to a shared_ptr instead of a plain pointer to the underlying type. +This approach means that any instantiation of the type can be passed to methods taking the type by value, reference, pointer +or as a smart pointer. +The interested reader might want to look at the generated code, however, usage is simple and no different +handling is required from the target language. +For example, a simple use case of the above code from Java would be: +

    + +
    +
    +IntValue iv = new IntValue(1234);
    +int val1 = example.extractValue(iv);
    +int val2 = example.extractValueSmart(iv);
    +System.out.println(val1 + " " + val2);
    +
    +
    + +

    +This shared_ptr library works quite differently to SWIG's normal, but somewhat limited, +smart pointer handling. +The shared_ptr library does not generate extra wrappers, just for smart pointer handling, in addition to the proxy class. +The normal proxy class including inheritance relationships is generated as usual. +The only real change introduced by the %shared_ptr macro is that the proxy class stores a pointer to the shared_ptr instance instead of a raw pointer to the instance. +A proxy class derived from a base which is being wrapped with shared_ptr can and must be wrapped as a shared_ptr too. +In other words all classes in an inheritance hierarchy must all be used with the %shared_ptr macro. +For example the following code can be used with the base class shown earlier: +

    + +
    +
    +%shared_ptr(DerivedIntValue)
    +%inline %{
    +struct DerivedIntValue : IntValue {
    +  DerivedIntValue(int value) : IntValue(value) {}
    +  ...
    +};
    +%}
    +
    +
    + +

    +Note that if the %shared_ptr macro is omitted for any class in the inheritance hierarchy, it will +result in a C++ compiler error. +For example if the above %shared_ptr(DerivedIntValue) is omitted, the following is typical of the compiler error that will result: +

    + +
    +
    +example_wrap.cxx: In function ‘void Java_exampleJNI_delete_1DerivedIntValue(JNIEnv*, _jclass*, jlong)’:
    +example_wrap.cxx:3169: error: ‘smartarg1’ was not declared in this scope
    +
    +
    + +

    +A shared_ptr of the derived class can now be passed to a method where the base is expected in the target language, just as it can in C++: +

    + +
    +
    +DerivedIntValue div = new DerivedIntValue(5678);
    +int val3 = example.extractValue(div);
    +int val4 = example.extractValueSmart(div);
    +
    +

    8.5 Utility Libraries

    diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 47ed38186..f9bfc8ec6 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -56,7 +56,7 @@
  • Exception specifications
  • Exception handling with %catches
  • Pointers to Members -
  • Smart pointers and operator->() +
  • Smart pointers and operator->()
  • Using declarations and inheritance
  • Nested classes
  • A brief rant about const-correctness @@ -4408,7 +4408,7 @@ when checking types. However, no such support is currently provided for member pointers.

    -

    6.24 Smart pointers and operator->()

    +

    6.24 Smart pointers and operator->()

    diff --git a/Lib/csharp/std_shared_ptr.i b/Lib/csharp/std_shared_ptr.i new file mode 100644 index 000000000..df873679c --- /dev/null +++ b/Lib/csharp/std_shared_ptr.i @@ -0,0 +1,2 @@ +#define SWIG_SHARED_PTR_NAMESPACE std +%include diff --git a/Lib/java/std_shared_ptr.i b/Lib/java/std_shared_ptr.i new file mode 100644 index 000000000..df873679c --- /dev/null +++ b/Lib/java/std_shared_ptr.i @@ -0,0 +1,2 @@ +#define SWIG_SHARED_PTR_NAMESPACE std +%include diff --git a/Lib/python/std_shared_ptr.i b/Lib/python/std_shared_ptr.i new file mode 100644 index 000000000..df873679c --- /dev/null +++ b/Lib/python/std_shared_ptr.i @@ -0,0 +1,2 @@ +#define SWIG_SHARED_PTR_NAMESPACE std +%include diff --git a/Lib/shared_ptr.i b/Lib/shared_ptr.i index 77e868de2..450493db4 100644 --- a/Lib/shared_ptr.i +++ b/Lib/shared_ptr.i @@ -1,3 +1,5 @@ +// This is a helper file for shared_ptr and should not be included directly. + // The main implementation detail in using this smart pointer of a type is to customise the code generated // to use a pointer to the smart pointer of the type, rather than the usual pointer to the underlying type. // So for some type T, shared_ptr * is used rather than T *.