mirror of https://github.com/swig/swig
Fix for STL containers static member and global variables
For UTL languages. Previously a copy of the STL container was made into a target language container when reading the variable. Changes, such as adjusting an element or adding/erasing elements, were made to the copy of the container rather the actual underlying C++ container. Also applies to const reference STL static members. Issue #2745
This commit is contained in:
parent
d82dc29c41
commit
747c3ff18a
|
@ -7,6 +7,26 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.2.1 (in progress)
|
||||
===========================
|
||||
|
||||
2024-02-18: wsfulton
|
||||
#2745 Fix for wrapping STL containers that are static member variables
|
||||
or global variables (most scripting languages). Previously a copy of the
|
||||
STL container was made into a target language container when reading the
|
||||
variable. Changes, such as adjusting an element or adding/erasing
|
||||
elements, were made to the copy of the container rather the actual
|
||||
underlying C++ container. Also applies to const reference STL static
|
||||
members.
|
||||
|
||||
If you really need the old behaviour, add in the typemap that provided
|
||||
used to provide it. For example, for std::list< int > and
|
||||
const std::list< int >&, use:
|
||||
|
||||
%typemap(varout,noblock=1,fragment="SWIG_" "Traits" "_" {std::list< int >})
|
||||
std::list< int >, const std::list< int >& {
|
||||
$result = swig::from(static_cast< std::list< int > >($1));
|
||||
}
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2024-02-15: olly
|
||||
Improve type deduction for enum values in expressions.
|
||||
|
||||
|
|
|
@ -150,3 +150,17 @@ int sum(int v) {
|
|||
return v;
|
||||
}
|
||||
%}
|
||||
|
||||
// Variables
|
||||
%inline %{
|
||||
struct VariableHolder {
|
||||
static std::vector<int> static_variable;
|
||||
std::vector<int> instance_variable;
|
||||
};
|
||||
std::vector<int> VariableHolder::static_variable;
|
||||
std::vector<int> global_variable;
|
||||
|
||||
void vector_append(std::vector<int>& vec, int val) {
|
||||
vec.push_back(val);
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -68,6 +68,18 @@ if [i for i in mii.items()] != [(1, 2)]:
|
|||
raise RuntimeError("iteritems")
|
||||
|
||||
|
||||
# map global variable
|
||||
li_std_map.populate(li_std_map.cvar.MyMap)
|
||||
li_std_map.cvar.MyMap["eeeeee"] = 6
|
||||
keys = " ".join([k for k in list(li_std_map.cvar.MyMap.keys())])
|
||||
if keys != "a aa zzz xxxx aaaaa eeeeee":
|
||||
raise RuntimeError("Keys are wrong or in wrong order: " + keys)
|
||||
|
||||
values = " ".join([str(v) for v in list(li_std_map.cvar.MyMap.values())])
|
||||
if values != "1 2 3 4 5 6":
|
||||
raise RuntimeError("Values are wrong or in wrong order: " + values)
|
||||
|
||||
|
||||
slmap = li_std_map.StringLengthNumberMap()
|
||||
li_std_map.populate(slmap)
|
||||
|
||||
|
|
|
@ -8,3 +8,27 @@ try:
|
|||
raise RuntimeError("Using None should result in a TypeError")
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
|
||||
# Variables
|
||||
vh = VariableHolder()
|
||||
vector_append(vh.instance_variable, 10)
|
||||
if vh.instance_variable[0] != 10:
|
||||
raise RuntimeError("instance_variable check")
|
||||
vh.instance_variable.clear()
|
||||
if len(vh.instance_variable) != 0:
|
||||
raise RuntimeError("instance_variable clear")
|
||||
|
||||
vector_append(cvar.VariableHolder_static_variable, 20)
|
||||
if cvar.VariableHolder_static_variable[0] != 20:
|
||||
raise RuntimeError("static_variable check")
|
||||
cvar.VariableHolder_static_variable.clear()
|
||||
if len(cvar.VariableHolder_static_variable) != 0:
|
||||
raise RuntimeError("static_variable clear")
|
||||
|
||||
vector_append(cvar.global_variable, 30)
|
||||
if cvar.global_variable[0] != 30:
|
||||
raise RuntimeError("global_variable check")
|
||||
cvar.global_variable.clear()
|
||||
if len(cvar.global_variable) != 0:
|
||||
raise RuntimeError("global_variable clear")
|
||||
|
|
|
@ -43,6 +43,16 @@ m.each_key { |k| pm[k] = m[k] }
|
|||
m.each_key { |k| swig_assert_equal("pm[#{k.inspect}]", "m[#{k.inspect}]", binding) }
|
||||
EOF
|
||||
|
||||
|
||||
Li_std_map::populate(Li_std_map.MyMap)
|
||||
Li_std_map.MyMap["eeeeee"] = 6
|
||||
swig_assert( "Li_std_map.MyMap['a'] == 1", binding )
|
||||
swig_assert( "Li_std_map.MyMap['aa'] == 2", binding )
|
||||
swig_assert( "Li_std_map.MyMap['zzz'] == 3", binding )
|
||||
swig_assert( "Li_std_map.MyMap['xxxx'] == 4", binding )
|
||||
swig_assert( "Li_std_map.MyMap['aaaaa'] == 5", binding )
|
||||
swig_assert( "Li_std_map.MyMap['eeeeee'] == 6", binding )
|
||||
|
||||
mii = Li_std_map::IntIntMap.new
|
||||
|
||||
mii[1] = 1
|
||||
|
|
|
@ -260,3 +260,20 @@ begin
|
|||
lv = LanguageVector.new('crapola')
|
||||
rescue
|
||||
end
|
||||
|
||||
# Variables
|
||||
vh = VariableHolder.new
|
||||
vector_append(vh.instance_variable, 10)
|
||||
swig_assert_equal("vh.instance_variable[0]", "10", binding)
|
||||
vh.instance_variable.clear
|
||||
swig_assert_equal("vh.instance_variable.empty?", "true", binding)
|
||||
|
||||
vector_append(VariableHolder.static_variable, 20)
|
||||
swig_assert_equal("VariableHolder.static_variable[0]", "20", binding)
|
||||
VariableHolder.static_variable.clear
|
||||
swig_assert_equal("VariableHolder.static_variable.empty?", "true", binding)
|
||||
|
||||
vector_append(Li_std_vector::global_variable, 30)
|
||||
swig_assert_equal("Li_std_vector::global_variable[0]", "30", binding)
|
||||
Li_std_vector::global_variable.clear
|
||||
swig_assert_equal("Li_std_vector::global_variable.empty?", "true", binding)
|
||||
|
|
|
@ -183,11 +183,32 @@
|
|||
%ptr_input_typemap(%arg(CheckCode),%arg(AsPtrMeth),%arg(AsPtrFrag),Type);
|
||||
%enddef
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* typemap definition for types with from method for ptr types
|
||||
* Same as typemaps_from but without varout typemap
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
%define %ptr_typemaps_from(FromMeth, FromFrag, Type...)
|
||||
%value_out_typemap(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
/* No varout typemap */
|
||||
%value_constcode_typemap(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
%value_directorin_typemap(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
%value_throws_typemap(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
%value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
%enddef
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* typemap definition for types with asptr/from methods
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
%define %typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type...)
|
||||
%typemaps_asptr(%arg(CheckCode), %arg(AsPtrMeth), %arg(AsPtrFrag), Type)
|
||||
%ptr_typemaps_from(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
%ptr_inout_typemap(Type);
|
||||
%enddef
|
||||
|
||||
// Same as typemaps_asptrfrom but defines a varout typemap to wrap with value semantics instead of the default pointer semantics
|
||||
%define %_typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type...)
|
||||
%typemaps_asptr(%arg(CheckCode), %arg(AsPtrMeth), %arg(AsPtrFrag), Type)
|
||||
%typemaps_from(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
%ptr_inout_typemap(Type);
|
||||
|
@ -198,7 +219,7 @@
|
|||
*---------------------------------------------------------------------*/
|
||||
|
||||
%define %typemaps_asptrfromn(CheckCode, Type...)
|
||||
%typemaps_asptrfrom(%arg(CheckCode),
|
||||
%_typemaps_asptrfrom(%arg(CheckCode),
|
||||
%arg(SWIG_AsPtr(Type)),
|
||||
%arg(SWIG_From(Type)),
|
||||
%arg(SWIG_AsPtr_frag(Type)),
|
||||
|
|
|
@ -180,6 +180,7 @@
|
|||
/*---------------------------------------------------------------------
|
||||
* typemap definition for types with from method
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
%define %typemaps_from(FromMeth, FromFrag, Type...)
|
||||
%value_out_typemap(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
%value_varout_typemap(%arg(FromMeth), %arg(FromFrag), Type);
|
||||
|
@ -191,7 +192,7 @@
|
|||
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* typemap definition for types with alval/from method
|
||||
* typemap definition for types with asval/from method
|
||||
*---------------------------------------------------------------------*/
|
||||
|
||||
%define %typemaps_asvalfrom(CheckCode, AsValMeth, FromMeth,
|
||||
|
|
Loading…
Reference in New Issue