Merge remote-tracking branch 'upstream/master' into OCaml-INPUT-OUTPUT-INOUT-primitives
This commit is contained in:
commit
5a58f9a87b
25 changed files with 354 additions and 23 deletions
|
|
@ -7,6 +7,15 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.0.0 (in progress)
|
||||
===========================
|
||||
|
||||
2019-02-18: jakecobb
|
||||
[Python] #945 #1234 Elements in std::vector memory access fix.
|
||||
|
||||
Accessing an element in a std::vector obtains a reference to the element via an
|
||||
iterator pointing to the element in the container. If the vector is garbage collected,
|
||||
the SWIG wrapper containing the pointer to the element becomes invalid. The fix is
|
||||
to obtain a back-reference to the container by the wrapper to the element in the Python
|
||||
layer to prevent the garbage collector from destroying the underlying container.
|
||||
|
||||
2019-02-17: wsfulton
|
||||
Fix typemap matching to expand template parameters when the name contains
|
||||
template parameters. In the %typemap below the type is T and the name is X<T>::make
|
||||
|
|
|
|||
|
|
@ -1828,7 +1828,7 @@ Consider the following C++ code:
|
|||
<pre>
|
||||
struct Wheel {
|
||||
int size;
|
||||
Wheel(int sz) : size(sz) {}
|
||||
Wheel(int sz = 0) : size(sz) {}
|
||||
};
|
||||
|
||||
class Bike {
|
||||
|
|
|
|||
|
|
@ -3711,7 +3711,7 @@ Below are some practical steps that should help meet these requirements.
|
|||
</li>
|
||||
<li>
|
||||
Copying an existing language module and adapting the source for it is likely to be the most efficient
|
||||
approach to fully developing a new module as a numbe of corner cases are covered in the existing implementations.
|
||||
approach to fully developing a new module as a number of corner cases are covered in the existing implementations.
|
||||
The most advanced scripting languages are Python and Ruby.
|
||||
The most advanced compiled target languages are Java and C#.
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -8295,7 +8295,7 @@ Consider the following C++ code:
|
|||
<pre>
|
||||
struct Wheel {
|
||||
int size;
|
||||
Wheel(int sz) : size(sz) {}
|
||||
Wheel(int sz = 0) : size(sz) {}
|
||||
};
|
||||
|
||||
class Bike {
|
||||
|
|
|
|||
|
|
@ -5452,7 +5452,7 @@ Consider the following C++ code:
|
|||
#include <iostream>
|
||||
struct Wheel {
|
||||
int size;
|
||||
Wheel(int sz) : size(sz) {}
|
||||
Wheel(int sz = 0) : size(sz) {}
|
||||
~Wheel() { std::cout << "~Wheel" << std::endl; }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4616,7 +4616,7 @@ except Error, e:
|
|||
|
||||
<p>
|
||||
Details of how to tailor code for handling the caught C++ exception and converting it into the target language's exception/error handling mechanism
|
||||
is outlined in the <a href="Typemaps.html#throws_typemap">"throws" typemap</a> section.
|
||||
is outlined in the <a href="Typemaps.html#Typemaps_throws_typemap">"throws" typemap</a> section.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%typemap(argout) (int &x, int &y) {
|
||||
%typemap(argout) (const int &x, const int &y) {
|
||||
swig_result = caml_list_append(swig_result, caml_val_int(*$1));
|
||||
swig_result = caml_list_append(swig_result, caml_val_int(*$2));
|
||||
}
|
||||
|
||||
%{
|
||||
extern "C" void factor(int &x, int &y);
|
||||
extern "C" void factor(const int &x, const int &y);
|
||||
%}
|
||||
|
||||
extern "C" void factor(int &x, int &y);
|
||||
extern "C" void factor(const int &x, const int &y);
|
||||
|
|
|
|||
|
|
@ -647,6 +647,7 @@ CPP_STD_TEST_CASES += \
|
|||
li_std_pair_using \
|
||||
li_std_string \
|
||||
li_std_vector \
|
||||
li_std_vector_back_reference \
|
||||
li_std_vector_enum \
|
||||
li_std_vector_member_var\
|
||||
li_std_vector_ptr \
|
||||
|
|
|
|||
14
Examples/test-suite/li_std_vector_back_reference.i
Normal file
14
Examples/test-suite/li_std_vector_back_reference.i
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
%module li_std_vector_back_reference
|
||||
|
||||
%include <std_vector.i>
|
||||
|
||||
%inline %{
|
||||
// #include <iostream>
|
||||
struct Wheel {
|
||||
int size;
|
||||
Wheel(int sz = 0) : size(sz) {}
|
||||
// ~Wheel() { std::cout << "~Wheel" << std::endl; }
|
||||
};
|
||||
%}
|
||||
|
||||
%template(VectorWheel) std::vector<Wheel>;
|
||||
53
Examples/test-suite/ocaml/extend_placement_runme.ml
Normal file
53
Examples/test-suite/ocaml/extend_placement_runme.ml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
open Swig
|
||||
open Extend_placement
|
||||
|
||||
let _ =
|
||||
let f = new_Foo '() in
|
||||
assert (f -> spam () as int = 1);
|
||||
assert (new_Foo '(1) -> spam () as int = 1);
|
||||
let f = new_Foo '(1, 1) in
|
||||
assert (f -> spam () as int = 1);
|
||||
assert (f -> spam ("hello") as int = 2);
|
||||
assert (f -> spam (1) as int = 1);
|
||||
assert (f -> spam (1, 2) as int = 3);
|
||||
assert (f -> spam (2, 4, 6) as int = 6);
|
||||
assert (f -> spam (f) as int = 0);
|
||||
let arg = C_double 1. in
|
||||
assert (f -> spam (f, arg) as int = 0);
|
||||
|
||||
assert (new_Bar '() -> spam () as int = 1);
|
||||
let b = new_Bar '(1) in
|
||||
assert (b -> spam () as int = 1);
|
||||
assert (b -> spam ("hello") as int = 2);
|
||||
assert (b -> spam (1) as int = 1);
|
||||
assert (b -> spam (1, 2) as int = 3);
|
||||
assert (b -> spam (2, 4, 6) as int = 6);
|
||||
assert (b -> spam (b) as int = 0);
|
||||
let arg = C_double 1. in
|
||||
assert (b -> spam (b, arg) as int = 0);
|
||||
|
||||
assert (new_FooTi '() -> spam () as int = 1);
|
||||
assert (new_FooTi '(1) -> spam () as int = 1);
|
||||
let f = new_FooTi '(1, 1) in
|
||||
assert (f -> spam () as int = 1);
|
||||
assert (f -> spam ("hello") as int = 2);
|
||||
assert (f -> spam (1) as int = 1);
|
||||
assert (f -> spam (1, 2) as int = 3);
|
||||
assert (f -> spam (2, 4, 6) as int = 6);
|
||||
let foo = new_Foo '() in
|
||||
assert (f -> spam (foo) as int = 0);
|
||||
let arg = C_double 1. in
|
||||
assert (f -> spam (foo, arg) as int = 0);
|
||||
|
||||
assert (new_BarTi '() -> spam () as int = 1);
|
||||
let b = new_BarTi '(1) in
|
||||
assert (b -> spam () as int = 1);
|
||||
assert (b -> spam ("hello") as int = 2);
|
||||
assert (b -> spam (1) as int = 1);
|
||||
assert (b -> spam (1, 2) as int = 3);
|
||||
assert (b -> spam (2, 4, 6) as int = 6);
|
||||
let bar = new_Bar '() in
|
||||
assert (b -> spam (bar) as int = 0);
|
||||
let arg = C_double 1. in
|
||||
assert (b -> spam (bar, arg) as int = 0);
|
||||
;;
|
||||
15
Examples/test-suite/ocaml/global_vars_runme.ml
Normal file
15
Examples/test-suite/ocaml/global_vars_runme.ml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
open Swig
|
||||
open Global_vars
|
||||
|
||||
_init '()
|
||||
|
||||
let _ =
|
||||
assert (_b '() as string = "string b");
|
||||
assert (_b '("a string value") as string = "a string value");
|
||||
assert (_b '() as string = "a string value");
|
||||
assert (_x '() as int = 1234);
|
||||
assert (_x '(9876) as int = 9876);
|
||||
assert (_x '() as int = 9876);
|
||||
assert (_Hi '() as int = 0);
|
||||
assert (_Hola '() as int = 1);
|
||||
;;
|
||||
60
Examples/test-suite/ocaml/overload_template_runme.ml
Normal file
60
Examples/test-suite/ocaml/overload_template_runme.ml
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
open Swig
|
||||
open Overload_template
|
||||
|
||||
let _ =
|
||||
assert (_foo '() as int = 3);
|
||||
assert (_maximum '(3, 4) as int = 4);
|
||||
assert (_maximum '(3.4, 5.2) as float > 5.);
|
||||
assert (_mix1 '("hi") as int = 101);
|
||||
assert (_mix1 '(1.0, 1.0) as int = 102);
|
||||
assert (_mix1 '(1.0) as int = 103);
|
||||
assert (_mix2 '("hi") as int = 101);
|
||||
assert (_mix2 '(1.0, 1.0) as int = 102);
|
||||
assert (_mix2 '(1.0) as int = 103);
|
||||
assert (_mix3 '("hi") as int = 101);
|
||||
assert (_mix3 '(1.0, 1.0) as int = 102);
|
||||
assert (_mix3 '(1.0) as int = 103);
|
||||
|
||||
assert (_overtparams1 '(100) as int = 10);
|
||||
assert (_overtparams1 '(100.0, 100) as int = 20);
|
||||
assert (_overtparams2 '(100.0, 100) as int = 40);
|
||||
assert (_overloaded '() as int = 60);
|
||||
assert (_overloaded '(100.0, 100) as int = 70);
|
||||
assert (_overloadedagain '("hello") as int = 80);
|
||||
assert (_overloadedagain '() as int = 90);
|
||||
|
||||
assert (_specialization '(10) as int = 202);
|
||||
assert (_specialization '(10.0) as int = 203);
|
||||
assert (_specialization '(10, 10) as int = 204);
|
||||
assert (_specialization '(10.0, 10.0) as int = 205);
|
||||
assert (_specialization '("hi", "hi") as int = 201);
|
||||
|
||||
assert (_xyz '() = C_void);
|
||||
assert (_xyz_int '() = C_void);
|
||||
assert (_xyz_double '() = C_void);
|
||||
|
||||
assert (_overload '("hi") as int = 0);
|
||||
assert (_overload '(1) as int = 10);
|
||||
assert (_overload '(1, 1) as int = 20);
|
||||
assert (_overload '(1, "hello") as int = 30);
|
||||
let k = new_Klass '() in
|
||||
assert (_overload '(k) as int = 10);
|
||||
assert (_overload '(k, k) as int = 20);
|
||||
assert (_overload '(k, "hello") as int = 30);
|
||||
assert (_overload '(10.0, "hi") as int = 40);
|
||||
assert (_overload '() as int = 50);
|
||||
|
||||
assert (_nsoverload '("hi") as int = 1000);
|
||||
assert (_nsoverload '(1) as int = 1010);
|
||||
assert (_nsoverload '(1, 1) as int = 1020);
|
||||
assert (_nsoverload '(1, "hello") as int = 1030);
|
||||
assert (_nsoverload '(k) as int = 1010);
|
||||
assert (_nsoverload '(k, k) as int = 1020);
|
||||
assert (_nsoverload '(k, "hello") as int = 1030);
|
||||
assert (_nsoverload '(10.0, "hi") as int = 1040);
|
||||
assert (_nsoverload '() as int = 1050);
|
||||
|
||||
assert (_A_foo '(1) = C_void);
|
||||
let b = new_B '() in
|
||||
assert (b -> foo(1) = C_void);
|
||||
;;
|
||||
|
|
@ -22,7 +22,7 @@ let _ =
|
|||
|
||||
let _ = _var_short (_createref_short (C_short 10)) in
|
||||
assert (_value_short (_var_short '()) as int = 10);
|
||||
|
||||
|
||||
let _ = _var_unsigned_short (_createref_unsigned_short (C_ushort 10)) in
|
||||
assert (_value_unsigned_short (_var_unsigned_short '()) as int = 10);
|
||||
|
||||
|
|
|
|||
10
Examples/test-suite/ocaml/sizet_runme.ml
Normal file
10
Examples/test-suite/ocaml/sizet_runme.ml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
open Swig
|
||||
open Sizet
|
||||
|
||||
let _ =
|
||||
let s = C_int64 2000L in
|
||||
assert (_test1 '(s) as int = 2000);
|
||||
assert (_test2 '(s) as int = 2000);
|
||||
assert (_test3 '(s) as int = 2000);
|
||||
assert (_test4 '(s) as int = 2000);
|
||||
;;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
open Swig
|
||||
open Template_default_arg_overloaded_extend
|
||||
|
||||
let _ =
|
||||
let rs = new_ResultSet '() and sp = new_SearchPoint '() in
|
||||
assert (rs -> go_get_method (0, sp) as int = -1);
|
||||
assert (rs -> go_get_method (0, sp, 100) as int = 100);
|
||||
assert (rs -> go_get_template (0, sp) as int = -2);
|
||||
assert (rs -> go_get_template (0, sp, 100) as int = 100);
|
||||
|
||||
assert (rs -> over () as string = "over(int)");
|
||||
assert (rs -> over (10) as string = "over(int)");
|
||||
assert (rs -> over (sp) as string = "over(giai2::SearchPoint, int)");
|
||||
assert (rs -> over (sp, 10) as string = "over(giai2::SearchPoint, int)");
|
||||
assert (rs -> over (true, sp) as string = "over(bool, gaia2::SearchPoint, int)");
|
||||
assert (rs -> over (true, sp, 10) as string = "over(bool, gaia2::SearchPoint, int)");
|
||||
;;
|
||||
52
Examples/test-suite/ocaml/template_default_arg_runme.ml
Normal file
52
Examples/test-suite/ocaml/template_default_arg_runme.ml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
open Swig
|
||||
open Template_default_arg
|
||||
|
||||
let _ =
|
||||
let helloInt = new_Hello_int '() and enumArg = _hi '() in
|
||||
assert (helloInt -> foo (enumArg) = C_void);
|
||||
assert (helloInt -> foo () = C_void);
|
||||
|
||||
let x = new_X_int '() in
|
||||
assert (x -> meth (20.0, 200) as int = 200);
|
||||
assert (x -> meth (20) as int = 20);
|
||||
assert (x -> meth () as int = 0);
|
||||
|
||||
let x = new_Y_unsigned '() in
|
||||
let args = C_list [ C_double 20.0 ; C_uint 200l ] in
|
||||
assert (x -> meth (args) as int = 200);
|
||||
let args = C_uint 20l in
|
||||
assert (x -> meth (args) as int = 20);
|
||||
assert (x -> meth () as int = 0);
|
||||
|
||||
let x = new_X_longlong '() in
|
||||
assert (x -> meth (20.0) as int = 0);
|
||||
let x = new_X_longlong '(20.0) in
|
||||
assert (x -> meth (20.0) as int = 0);
|
||||
let args = C_list [ C_double 20.0 ; C_int64 200L ] in
|
||||
let x = new_X_longlong '(args) in
|
||||
assert (x -> meth (20.0) as int = 0);
|
||||
|
||||
let x = new_X_int '() in
|
||||
assert (x -> meth (20.0) as int = 0);
|
||||
let x = new_X_int '(20.0) in
|
||||
assert (x -> meth (20.0) as int = 0);
|
||||
let x = new_X_int '(20.0, 200) in
|
||||
assert (x -> meth (20.0) as int = 0);
|
||||
|
||||
let arg = new_Foo_int '() in
|
||||
assert (_ott '(arg) as int = 30);
|
||||
assert (_ott '() as int = 10);
|
||||
assert (_ott '(1) as int = 10);
|
||||
assert (_ott '(1, 1) as int = 10);
|
||||
assert (_ott '("hi") as int = 20);
|
||||
assert (_ott '("hi", 1) as int = 20);
|
||||
assert (_ott '("hi", 1, 1) as int = 20);
|
||||
|
||||
let arg = new_Hello_int '() in
|
||||
assert (_ottstring '(arg, "hi") as int = 40);
|
||||
assert (_ottstring '(arg) as int = 40);
|
||||
assert (_ottint '(arg, 1) as int = 50);
|
||||
assert (_ottint '(arg) as int = 50);
|
||||
assert (_ott '(arg, 1.0) as int = 60);
|
||||
assert (_ott '(arg) as int = 60);
|
||||
;;
|
||||
11
Examples/test-suite/ocaml/typedef_reference_runme.ml
Normal file
11
Examples/test-suite/ocaml/typedef_reference_runme.ml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
open Swig
|
||||
open Typedef_reference
|
||||
|
||||
let _ =
|
||||
let i = _copy_intp '(2) in
|
||||
assert (_somefunc '(i) as int = 2);
|
||||
assert (_delete_intp '(i) = C_void);
|
||||
let i = _copy_intp '(3) in
|
||||
assert (_otherfunc '(i) as int = 3);
|
||||
assert (_delete_intp '(i) = C_void);
|
||||
;;
|
||||
10
Examples/test-suite/ocaml/wrapmacro_runme.ml
Normal file
10
Examples/test-suite/ocaml/wrapmacro_runme.ml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
open Swig
|
||||
open Wrapmacro
|
||||
|
||||
let _ =
|
||||
let args = C_list [ C_int64 2L ; C_int64 1L ] in
|
||||
assert (_maximum '(args) as int = 2);
|
||||
let args = C_list [ C_double (2. /. 7.) ; C_double 256. ] in
|
||||
assert (_maximum '(args) as float = 256.);
|
||||
assert (_GUINT16_SWAP_LE_BE_CONSTANT '(0x1234) as int = 0x3412);
|
||||
;;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
from li_std_vector_back_reference import *
|
||||
|
||||
def first_element():
|
||||
v = VectorWheel((Wheel(11), Wheel(22)))
|
||||
# v will be deleted after exit from this method
|
||||
return v[0]
|
||||
|
||||
size = first_element().size
|
||||
if size != 11:
|
||||
raise RuntimeError("Back reference not working {}".format(size))
|
||||
|
|
@ -62,7 +62,7 @@ extern "C" {
|
|||
SWIG_TypeCheckStruct(source_type, dest_type );
|
||||
#ifdef TYPE_CAST_VERBOSE
|
||||
fprintf( stderr, "Typecheck -> %s\n",
|
||||
tc ? tc->str : "<none>" );
|
||||
tc ? tc->type->str : "<none>" );
|
||||
#endif
|
||||
if( tc ) {
|
||||
int newmemory = 0;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
%include <std/std_except.i>
|
||||
|
||||
%apply size_t { std::size_t };
|
||||
%apply const size_t& { const std::size_t& };
|
||||
|
||||
%{
|
||||
#include <string>
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class wstring;
|
|||
%typemap(out) string * {
|
||||
$result = caml_val_string_len((*$1).c_str(),(*$1).size());
|
||||
}
|
||||
%typemap(typecheck) string, const string & = char *;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CHARPTR_ARRAY
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@
|
|||
long, signed long, unsigned long,
|
||||
long long, signed long long, unsigned long long,
|
||||
const long &, const signed long &, const unsigned long &,
|
||||
const long long &, const signed long long &, const unsigned long long &
|
||||
const long long &, const signed long long &, const unsigned long long &,
|
||||
size_t, const size_t &
|
||||
{
|
||||
if( !Is_block($input) ) $1 = 0;
|
||||
else {
|
||||
|
|
@ -135,24 +136,42 @@
|
|||
}
|
||||
|
||||
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] {
|
||||
void *ptr;
|
||||
$1 = !caml_ptr_val_internal($input, &ptr,$descriptor);
|
||||
if (!Is_block($input) || !(SWIG_Tag_val($input) == C_obj || SWIG_Tag_val($input) == C_ptr)) {
|
||||
$1 = 0;
|
||||
} else {
|
||||
void *ptr;
|
||||
$1 = !caml_ptr_val_internal($input, &ptr, $descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE {
|
||||
void *ptr;
|
||||
$1 = !caml_ptr_val_internal($input, &ptr, $&1_descriptor);
|
||||
swig_type_info *typeinfo;
|
||||
if (!Is_block($input)) {
|
||||
$1 = 0;
|
||||
} else {
|
||||
switch (SWIG_Tag_val($input)) {
|
||||
case C_obj: {
|
||||
void *ptr;
|
||||
$1 = !caml_ptr_val_internal($input, &ptr, $&1_descriptor);
|
||||
break;
|
||||
}
|
||||
case C_ptr: {
|
||||
typeinfo = (swig_type_info *)SWIG_Int64_val(SWIG_Field($input, 1));
|
||||
$1 = SWIG_TypeCheck("$1_type", typeinfo) != NULL;
|
||||
break;
|
||||
}
|
||||
default: $1 = 0; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
%typecheck(SWIG_TYPECHECK_VOIDPTR) void * {
|
||||
void *ptr;
|
||||
$1 = !caml_ptr_val_internal($input, &ptr, 0);
|
||||
}
|
||||
|
||||
%typecheck(SWIG_TYPECHECK_SWIGOBJECT) CAML_VALUE "$1 = 1;"
|
||||
|
||||
%define INPUT_OUTPUT_INOUT_TYPEMAPS(type, c_to_ocaml, ocaml_to_c)
|
||||
%typemap(in) type *INPUT(type temp), type &INPUT(type temp) {
|
||||
temp = (type)ocaml_to_c($input);
|
||||
|
|
|
|||
|
|
@ -132,11 +132,11 @@
|
|||
%typemap(varin) C_NAME {
|
||||
$1 = OCAML_TO_C($input);
|
||||
}
|
||||
%typemap(in) C_NAME & ($*1_ltype temp) {
|
||||
%typemap(in) const C_NAME & ($*1_ltype temp) {
|
||||
temp = ($*1_ltype) OCAML_TO_C($input);
|
||||
$1 = &temp;
|
||||
}
|
||||
%typemap(varin) C_NAME & {
|
||||
%typemap(varin) const C_NAME & {
|
||||
$1 = OCAML_TO_C($input);
|
||||
}
|
||||
%typemap(directorout) C_NAME {
|
||||
|
|
@ -149,10 +149,10 @@
|
|||
%typemap(varout) C_NAME {
|
||||
$result = C_TO_OCAML($1);
|
||||
}
|
||||
%typemap(varout) C_NAME & {
|
||||
%typemap(varout) const C_NAME & {
|
||||
$result = C_TO_OCAML($1);
|
||||
}
|
||||
%typemap(out) C_NAME & {
|
||||
%typemap(out) const C_NAME & {
|
||||
$result = C_TO_OCAML(*$1);
|
||||
}
|
||||
%typemap(directorin) C_NAME {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,48 @@
|
|||
|
||||
%include <std_except.i>
|
||||
|
||||
%fragment("container_owner_attribute_init", "init") {
|
||||
// thread safe initialization
|
||||
swig::container_owner_attribute();
|
||||
}
|
||||
|
||||
%fragment("reference_container_owner", "header", fragment="container_owner_attribute_init") {
|
||||
namespace swig {
|
||||
PyObject* container_owner_attribute() {
|
||||
static PyObject* attr = SWIG_Python_str_FromChar("__swig_container");
|
||||
return attr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct container_owner {
|
||||
// By default, do not add the back-reference (for value types)
|
||||
// Specialization below will check the reference for pointer types.
|
||||
static bool back_reference(PyObject* child, PyObject* owner) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct container_owner<swig::pointer_category> {
|
||||
/*
|
||||
* Call to add a back-reference to the owning object when returning a
|
||||
* reference from a container. Will only set the reference if child
|
||||
* is a SWIG wrapper object that does not own the pointer.
|
||||
*
|
||||
* returns whether the reference was set or not
|
||||
*/
|
||||
static bool back_reference(PyObject* child, PyObject* owner) {
|
||||
SwigPyObject* swigThis = SWIG_Python_GetSwigThis(child);
|
||||
if (swigThis && (swigThis->own & SWIG_POINTER_OWN) != SWIG_POINTER_OWN) {
|
||||
PyObject_SetAttr(child, container_owner_attribute(), owner);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
%fragment(SWIG_Traits_frag(swig::SwigPtr_PyObject),"header",fragment="StdTraits") {
|
||||
namespace swig {
|
||||
template <> struct traits<SwigPtr_PyObject > {
|
||||
|
|
@ -766,6 +808,12 @@ namespace swig
|
|||
size_type __len__() const {
|
||||
return self->size();
|
||||
}
|
||||
|
||||
// Although __getitem__, front, back actually use a const value_type& return type, the typemaps below
|
||||
// use non-const so that they can be easily overridden by users if necessary.
|
||||
%typemap(ret, fragment="reference_container_owner", noblock=1) value_type& __getitem__, value_type& front, value_type& back {
|
||||
(void)swig::container_owner<swig::traits<$*1_ltype>::category>::back_reference($result, $self);
|
||||
}
|
||||
}
|
||||
%enddef
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue