Add Octave support for std::unique_ptr and std::auto_ptr
Equivalent to Ruby/Python implementations.
This commit is contained in:
parent
1730e4126e
commit
2ccc9bd060
8 changed files with 341 additions and 20 deletions
|
|
@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.1.0 (in progress)
|
Version 4.1.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2022-08-02: wsfulton
|
||||||
|
[Octave] Add support for std::unique_ptr in std_unique_ptr.i.
|
||||||
|
Add support for std::auto_ptr in std_auto_ptr.i.
|
||||||
|
|
||||||
2022-08-01: wsfulton
|
2022-08-01: wsfulton
|
||||||
[Python] Add initialisers for additional members in PyHeapTypeObject
|
[Python] Add initialisers for additional members in PyHeapTypeObject
|
||||||
(builtin mode) for Python-3.11 - _ht_tpname, _spec_cache.
|
(builtin mode) for Python-3.11 - _ht_tpname, _spec_cache.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
%module cpp11_std_unique_ptr
|
%module cpp11_std_unique_ptr
|
||||||
|
|
||||||
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL)
|
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL) || defined(SWIGOCTAVE)
|
||||||
|
|
||||||
%include "std_string.i"
|
%include "std_string.i"
|
||||||
%include "std_unique_ptr.i"
|
%include "std_unique_ptr.i"
|
||||||
|
|
|
||||||
|
|
@ -12,17 +12,28 @@
|
||||||
#endif
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL)
|
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL) || defined(SWIGOCTAVE)
|
||||||
|
|
||||||
%include "std_string.i"
|
%include "std_string.i"
|
||||||
%include "std_auto_ptr.i"
|
%include "std_auto_ptr.i"
|
||||||
|
|
||||||
%auto_ptr(Klass)
|
%auto_ptr(Klass)
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
void show_cplusplus_version() {
|
||||||
|
printf("__cplusplus %d\n", (int)__cplusplus);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#if __cplusplus < 201703L
|
#if __cplusplus < 201703L
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// If <memory> has already been include (Octave does) then unfortunately gcc incorrectly still provides
|
||||||
|
// std::auto_ptr when _GLIBCXX_USE_DEPRECATED is defined by the compiler configuration/OS/who knows what!!
|
||||||
|
#include <memory> // Now need to include it in case _GLIBCXX_USE_DEPRECATED is defined and <memory> has not been included, argh
|
||||||
|
#if !defined(_GLIBCXX_USE_DEPRECATED)
|
||||||
// Simple std::auto_ptr implementation for testing after its removal in C++17
|
// Simple std::auto_ptr implementation for testing after its removal in C++17
|
||||||
namespace std {
|
namespace std {
|
||||||
template <class T> class auto_ptr {
|
template <class T> class auto_ptr {
|
||||||
|
|
@ -40,6 +51,8 @@ namespace std {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "swig_examples_lock.h"
|
#include "swig_examples_lock.h"
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
109
Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m
Normal file
109
Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
# do not dump Octave core
|
||||||
|
if exist("crash_dumps_octave_core", "builtin")
|
||||||
|
crash_dumps_octave_core(0);
|
||||||
|
endif
|
||||||
|
|
||||||
|
cpp11_std_unique_ptr
|
||||||
|
|
||||||
|
function checkCount(expected_count)
|
||||||
|
actual_count = Klass_getTotal_count();
|
||||||
|
if (actual_count != expected_count)
|
||||||
|
error("Counts incorrect, expected:%d actual:%d", expected_count, actual_count);
|
||||||
|
endif
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# unique_ptr as input
|
||||||
|
kin = Klass("KlassInput");
|
||||||
|
checkCount(1);
|
||||||
|
s = takeKlassUniquePtr(kin);
|
||||||
|
checkCount(0);
|
||||||
|
if (!strcmp(s, "KlassInput"))
|
||||||
|
error("Incorrect string: %s", s);
|
||||||
|
endif
|
||||||
|
if (!is_nullptr(kin))
|
||||||
|
error("is_nullptr failed");
|
||||||
|
endif
|
||||||
|
clear kin; # Should not fail, even though already deleted
|
||||||
|
checkCount(0);
|
||||||
|
|
||||||
|
kin = Klass("KlassInput");
|
||||||
|
checkCount(1);
|
||||||
|
s = takeKlassUniquePtr(kin);
|
||||||
|
checkCount(0);
|
||||||
|
if (!strcmp(s, "KlassInput"))
|
||||||
|
error("Incorrect string: %s", s);
|
||||||
|
endif
|
||||||
|
if (!is_nullptr(kin))
|
||||||
|
error("is_nullptr failed");
|
||||||
|
endif
|
||||||
|
exception_thrown = false;
|
||||||
|
try
|
||||||
|
takeKlassUniquePtr(kin);
|
||||||
|
catch e
|
||||||
|
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
|
||||||
|
error("incorrect exception message %s", e.message);
|
||||||
|
endif
|
||||||
|
exception_thrown = true;
|
||||||
|
end_try_catch
|
||||||
|
if (!exception_thrown)
|
||||||
|
error("double usage of takeKlassUniquePtr should have been an error");
|
||||||
|
endif
|
||||||
|
clear kin; # Should not fail, even though already deleted
|
||||||
|
checkCount(0);
|
||||||
|
|
||||||
|
kin = Klass("KlassInput");
|
||||||
|
exception_thrown = false;
|
||||||
|
try
|
||||||
|
notowned = get_not_owned_ptr(kin);
|
||||||
|
takeKlassUniquePtr(notowned);
|
||||||
|
catch e
|
||||||
|
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
|
||||||
|
error("incorrect exception message %s", e.message);
|
||||||
|
endif
|
||||||
|
exception_thrown = true;
|
||||||
|
end_try_catch
|
||||||
|
if (!exception_thrown)
|
||||||
|
error("Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||||
|
endif
|
||||||
|
clear kin;
|
||||||
|
checkCount(0);
|
||||||
|
|
||||||
|
kini = KlassInheritance("KlassInheritanceInput");
|
||||||
|
checkCount(1);
|
||||||
|
s = takeKlassUniquePtr(kini);
|
||||||
|
checkCount(0);
|
||||||
|
if (!strcmp(s, "KlassInheritanceInput"))
|
||||||
|
error("Incorrect string: %s", s);
|
||||||
|
endif
|
||||||
|
if (!is_nullptr(kini))
|
||||||
|
error("is_nullptr failed");
|
||||||
|
endif
|
||||||
|
clear kini; # Should not fail, even though already deleted
|
||||||
|
checkCount(0);
|
||||||
|
|
||||||
|
|
||||||
|
# unique_ptr as output
|
||||||
|
k1 = makeKlassUniquePtr("first");
|
||||||
|
if (!strcmp(k1.getLabel(), "first"))
|
||||||
|
error("wrong object label");
|
||||||
|
endif
|
||||||
|
|
||||||
|
k2 = makeKlassUniquePtr("second");
|
||||||
|
if (Klass_getTotal_count() != 2)
|
||||||
|
error("number of objects should be 2");
|
||||||
|
endif
|
||||||
|
|
||||||
|
clear k1;
|
||||||
|
if (Klass.getTotal_count() != 1)
|
||||||
|
error("number of objects should be 1");
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (!strcmp(k2.getLabel(), "second"))
|
||||||
|
error("wrong object label");
|
||||||
|
endif
|
||||||
|
|
||||||
|
clear k2;
|
||||||
|
if (Klass.getTotal_count() != 0)
|
||||||
|
error("no objects should be left");
|
||||||
|
endif
|
||||||
108
Examples/test-suite/octave/li_std_auto_ptr_runme.m
Normal file
108
Examples/test-suite/octave/li_std_auto_ptr_runme.m
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
# do not dump Octave core
|
||||||
|
if exist("crash_dumps_octave_core", "builtin")
|
||||||
|
crash_dumps_octave_core(0);
|
||||||
|
endif
|
||||||
|
|
||||||
|
li_std_auto_ptr
|
||||||
|
|
||||||
|
function checkCount(expected_count)
|
||||||
|
actual_count = Klass_getTotal_count();
|
||||||
|
if (actual_count != expected_count)
|
||||||
|
error("Counts incorrect, expected:%d actual:%d", expected_count, actual_count);
|
||||||
|
endif
|
||||||
|
end
|
||||||
|
|
||||||
|
# auto_ptr as input
|
||||||
|
kin = Klass("KlassInput");
|
||||||
|
checkCount(1);
|
||||||
|
s = takeKlassAutoPtr(kin);
|
||||||
|
checkCount(0);
|
||||||
|
if (!strcmp(s, "KlassInput"))
|
||||||
|
error("Incorrect string: %s", s);
|
||||||
|
endif
|
||||||
|
if (!is_nullptr(kin))
|
||||||
|
error("is_nullptr failed");
|
||||||
|
endif
|
||||||
|
clear kin; # Should not fail, even though already deleted
|
||||||
|
checkCount(0);
|
||||||
|
|
||||||
|
kin = Klass("KlassInput");
|
||||||
|
checkCount(1);
|
||||||
|
s = takeKlassAutoPtr(kin);
|
||||||
|
checkCount(0);
|
||||||
|
if (!strcmp(s, "KlassInput"))
|
||||||
|
error("Incorrect string: %s", s);
|
||||||
|
endif
|
||||||
|
if (!is_nullptr(kin))
|
||||||
|
error("is_nullptr failed");
|
||||||
|
endif
|
||||||
|
exception_thrown = false;
|
||||||
|
try
|
||||||
|
takeKlassAutoPtr(kin);
|
||||||
|
catch e
|
||||||
|
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
|
||||||
|
error("incorrect exception message %s", e.message);
|
||||||
|
endif
|
||||||
|
exception_thrown = true;
|
||||||
|
end_try_catch
|
||||||
|
if (!exception_thrown)
|
||||||
|
error("double usage of takeKlassAutoPtr should have been an error");
|
||||||
|
endif
|
||||||
|
clear kin; # Should not fail, even though already deleted
|
||||||
|
checkCount(0);
|
||||||
|
|
||||||
|
kin = Klass("KlassInput");
|
||||||
|
exception_thrown = false;
|
||||||
|
try
|
||||||
|
notowned = get_not_owned_ptr(kin);
|
||||||
|
takeKlassAutoPtr(notowned);
|
||||||
|
catch e
|
||||||
|
if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
|
||||||
|
error("incorrect exception message %s", e.message);
|
||||||
|
endif
|
||||||
|
exception_thrown = true;
|
||||||
|
end_try_catch
|
||||||
|
if (!exception_thrown)
|
||||||
|
error("Should have thrown 'Cannot release ownership as memory is not owned' error");
|
||||||
|
endif
|
||||||
|
clear kin;
|
||||||
|
checkCount(0);
|
||||||
|
|
||||||
|
kini = KlassInheritance("KlassInheritanceInput");
|
||||||
|
checkCount(1);
|
||||||
|
s = takeKlassAutoPtr(kini);
|
||||||
|
checkCount(0);
|
||||||
|
if (!strcmp(s, "KlassInheritanceInput"))
|
||||||
|
error("Incorrect string: %s", s);
|
||||||
|
endif
|
||||||
|
if (!is_nullptr(kini))
|
||||||
|
error("is_nullptr failed");
|
||||||
|
endif
|
||||||
|
clear kini; # Should not fail, even though already deleted
|
||||||
|
checkCount(0);
|
||||||
|
|
||||||
|
|
||||||
|
# auto_ptr as output
|
||||||
|
k1 = makeKlassAutoPtr("first");
|
||||||
|
if (!strcmp(k1.getLabel(), "first"))
|
||||||
|
error("wrong object label");
|
||||||
|
endif
|
||||||
|
|
||||||
|
k2 = makeKlassAutoPtr("second");
|
||||||
|
if (Klass_getTotal_count() != 2)
|
||||||
|
error("number of objects should be 2");
|
||||||
|
endif
|
||||||
|
|
||||||
|
clear k1;
|
||||||
|
if (Klass.getTotal_count() != 1)
|
||||||
|
error("number of objects should be 1");
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (!strcmp(k2.getLabel(), "second"))
|
||||||
|
error("wrong object label");
|
||||||
|
endif
|
||||||
|
|
||||||
|
clear k2;
|
||||||
|
if (Klass.getTotal_count() != 0)
|
||||||
|
error("no objects should be left");
|
||||||
|
endif
|
||||||
|
|
@ -232,7 +232,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
|
||||||
|
|
||||||
const swig_type_info *construct_type; // type of special type object
|
const swig_type_info *construct_type; // type of special type object
|
||||||
std::vector < type_ptr_pair > types; // our c++ base classes
|
std::vector < type_ptr_pair > types; // our c++ base classes
|
||||||
int own; // whether we call c++ destructors when we die
|
int thisown; // whether we call c++ destructors when we die
|
||||||
|
|
||||||
typedef std::pair < const swig_octave_member *, octave_value > member_value_pair;
|
typedef std::pair < const swig_octave_member *, octave_value > member_value_pair;
|
||||||
typedef std::map < std::string, member_value_pair > member_map;
|
typedef std::map < std::string, member_value_pair > member_map;
|
||||||
|
|
@ -412,7 +412,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
|
||||||
|
|
||||||
octave_swig_type(void *_ptr = 0, const swig_type_info *_type = 0, int _own = 0,
|
octave_swig_type(void *_ptr = 0, const swig_type_info *_type = 0, int _own = 0,
|
||||||
bool _always_static = false)
|
bool _always_static = false)
|
||||||
: module(0), construct_type(_ptr ? 0 : _type), own(_own),
|
: module(0), construct_type(_ptr ? 0 : _type), thisown(_own),
|
||||||
always_static(_always_static) {
|
always_static(_always_static) {
|
||||||
if (_type || _ptr)
|
if (_type || _ptr)
|
||||||
types.push_back(std::make_pair(_type, _ptr));
|
types.push_back(std::make_pair(_type, _ptr));
|
||||||
|
|
@ -426,7 +426,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
|
||||||
}
|
}
|
||||||
|
|
||||||
~octave_swig_type() {
|
~octave_swig_type() {
|
||||||
if (own) {
|
if (thisown) {
|
||||||
++count;
|
++count;
|
||||||
for (unsigned int j = 0; j < types.size(); ++j) {
|
for (unsigned int j = 0; j < types.size(); ++j) {
|
||||||
if (!types[j].first || !types[j].first->clientdata)
|
if (!types[j].first || !types[j].first->clientdata)
|
||||||
|
|
@ -559,7 +559,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
|
||||||
}
|
}
|
||||||
|
|
||||||
void merge(octave_swig_type &rhs) {
|
void merge(octave_swig_type &rhs) {
|
||||||
rhs.own = 0;
|
rhs.thisown = 0;
|
||||||
for (unsigned int j = 0; j < rhs.types.size(); ++j) {
|
for (unsigned int j = 0; j < rhs.types.size(); ++j) {
|
||||||
assert(!rhs.types[j].second.destroyed);
|
assert(!rhs.types[j].second.destroyed);
|
||||||
#ifdef SWIG_DIRECTORS
|
#ifdef SWIG_DIRECTORS
|
||||||
|
|
@ -582,35 +582,56 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
|
||||||
swig_member_const_iterator swig_members_begin() { return members.begin(); }
|
swig_member_const_iterator swig_members_begin() { return members.begin(); }
|
||||||
swig_member_const_iterator swig_members_end() { return members.end(); }
|
swig_member_const_iterator swig_members_end() { return members.end(); }
|
||||||
|
|
||||||
int cast(void **vptr, swig_type_info *type, int *_own, int flags) {
|
int cast(void **vptr, swig_type_info *type, int *own, int flags) {
|
||||||
int res = SWIG_ERROR;
|
int res = SWIG_ERROR;
|
||||||
if (_own)
|
int clear_pointer = 0;
|
||||||
*_own = own;
|
|
||||||
if (flags &SWIG_POINTER_DISOWN)
|
if (own)
|
||||||
own = 0;
|
*own = 0;
|
||||||
|
if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !thisown) {
|
||||||
|
return SWIG_ERROR_RELEASE_NOT_OWNED;
|
||||||
|
} else {
|
||||||
|
if (own)
|
||||||
|
*own = *own | thisown;
|
||||||
|
if (flags & SWIG_POINTER_DISOWN) {
|
||||||
|
thisown = 0;
|
||||||
|
}
|
||||||
|
if (flags & SWIG_POINTER_CLEAR) {
|
||||||
|
clear_pointer = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!type && types.size()) {
|
if (!type && types.size()) {
|
||||||
if(vptr)
|
if (vptr) {
|
||||||
*vptr = types[0].second.ptr;
|
*vptr = types[0].second.ptr;
|
||||||
|
if (clear_pointer)
|
||||||
|
types[0].second.ptr = 0;
|
||||||
|
}
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
for (unsigned int j = 0; j < types.size(); ++j)
|
for (unsigned int j = 0; j < types.size(); ++j)
|
||||||
if (type == types[j].first) {
|
if (type == types[j].first) {
|
||||||
if(vptr)
|
if (vptr) {
|
||||||
*vptr = types[j].second.ptr;
|
*vptr = types[j].second.ptr;
|
||||||
|
if (clear_pointer)
|
||||||
|
types[j].second.ptr = 0;
|
||||||
|
}
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
for (unsigned int j = 0; j < types.size(); ++j) {
|
for (unsigned int j = 0; j < types.size(); ++j) {
|
||||||
swig_cast_info *tc = SWIG_TypeCheck(types[j].first->name, type);
|
swig_cast_info *tc = SWIG_TypeCheck(types[j].first->name, type);
|
||||||
if (!tc)
|
if (!tc)
|
||||||
continue;
|
continue;
|
||||||
if(vptr) {
|
if (vptr) {
|
||||||
int newmemory = 0;
|
int newmemory = 0;
|
||||||
*vptr = SWIG_TypeCast(tc, types[j].second.ptr, &newmemory);
|
*vptr = SWIG_TypeCast(tc, types[j].second.ptr, &newmemory);
|
||||||
if (newmemory == SWIG_CAST_NEW_MEMORY) {
|
if (newmemory == SWIG_CAST_NEW_MEMORY) {
|
||||||
assert(_own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
|
assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
|
||||||
if (_own)
|
if (own)
|
||||||
*_own = *_own | SWIG_CAST_NEW_MEMORY;
|
*own = *own | SWIG_CAST_NEW_MEMORY;
|
||||||
}
|
}
|
||||||
|
if (clear_pointer)
|
||||||
|
types[j].second.ptr = 0;
|
||||||
}
|
}
|
||||||
res = SWIG_OK;
|
res = SWIG_OK;
|
||||||
break;
|
break;
|
||||||
|
|
@ -619,7 +640,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_owned() const {
|
bool is_owned() const {
|
||||||
return own;
|
return thisown;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SWIG_DIRECTORS
|
#ifdef SWIG_DIRECTORS
|
||||||
|
|
|
||||||
33
Lib/octave/std_auto_ptr.i
Normal file
33
Lib/octave/std_auto_ptr.i
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* 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(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
|
||||||
|
res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
|
||||||
|
if (!SWIG_IsOK(res)) {
|
||||||
|
if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
|
||||||
|
%releasenotowned_fail(res, "TYPE *", $symname, $argnum);
|
||||||
|
} else {
|
||||||
|
%argument_fail(res, "TYPE *", $symname, $argnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$1.reset((TYPE *)argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
%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 {};
|
||||||
|
}
|
||||||
33
Lib/octave/std_unique_ptr.i
Normal file
33
Lib/octave/std_unique_ptr.i
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* 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(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
|
||||||
|
res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
|
||||||
|
if (!SWIG_IsOK(res)) {
|
||||||
|
if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
|
||||||
|
%releasenotowned_fail(res, "TYPE *", $symname, $argnum);
|
||||||
|
} else {
|
||||||
|
%argument_fail(res, "TYPE *", $symname, $argnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$1.reset((TYPE *)argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
%typemap (out) std::unique_ptr< TYPE > %{
|
||||||
|
%set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
|
||||||
|
%}
|
||||||
|
|
||||||
|
%template() std::unique_ptr< TYPE >;
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <class T> class unique_ptr {};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue