Add test case for attributes with moderately complex templates
* New test case tests that %attribute macros correctly supports passing template with multiple parameters as class name or attribute type name * Some further changes were made to %attribute macros - now AttributeType is protected with %arg as well. This allows you to have attributes of type e.g. std::pair<int,int> etc Update CHANGES file for %attribute template fixes Closes #48
This commit is contained in:
parent
c956c4c87f
commit
3e188e508d
5 changed files with 192 additions and 10 deletions
|
|
@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
|
|||
Version 2.0.10 (in progress)
|
||||
============================
|
||||
|
||||
2013-05-25: Artem Serebriyskiy
|
||||
SVN Patch ticket #338 - fixes to %attribute macros for template usage
|
||||
with %arg.
|
||||
|
||||
2013-05-19: wsfulton
|
||||
Fix ccache-swig internal error bug due to premature file cleanup.
|
||||
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ CPP_TEST_CASES += \
|
|||
kind \
|
||||
langobj \
|
||||
li_attribute \
|
||||
li_attribute_template \
|
||||
li_boost_shared_ptr \
|
||||
li_boost_shared_ptr_bits \
|
||||
li_boost_shared_ptr_template \
|
||||
|
|
|
|||
110
Examples/test-suite/li_attribute_template.i
Normal file
110
Examples/test-suite/li_attribute_template.i
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
%module li_attribute_template
|
||||
|
||||
%include <exception.i>
|
||||
|
||||
//#define SWIG_ATTRIBUTE_TEMPLATE
|
||||
%include <attribute.i>
|
||||
%include <std_string.i>
|
||||
|
||||
%inline
|
||||
{
|
||||
class Foo {
|
||||
public:
|
||||
Foo( int _value ) { value = _value; }
|
||||
int value;
|
||||
};
|
||||
|
||||
template< class T1, class T2>
|
||||
struct pair{
|
||||
pair( T1 t1, T2 t2 ):
|
||||
first(t1), second(t2) {;}
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
};
|
||||
|
||||
template< class T1, class T2>
|
||||
struct C
|
||||
{
|
||||
C(int a, int b, int c) :
|
||||
_a(a), _b(b), _c(c), _d(a), _e(b),
|
||||
_f(a,b), _g(b,c)
|
||||
{
|
||||
|
||||
/*
|
||||
_f.first = _a;
|
||||
_f.second = _b;
|
||||
|
||||
_g.first = _b;
|
||||
_g.second = _c;
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
int get_value() const
|
||||
{
|
||||
return _a;
|
||||
}
|
||||
|
||||
void set_value(int aa)
|
||||
{
|
||||
_a = aa;
|
||||
}
|
||||
|
||||
/* only one ref method */
|
||||
int& get_ref()
|
||||
{
|
||||
return _b;
|
||||
}
|
||||
|
||||
Foo get_class_value() const { return _d; }
|
||||
void set_class_value( Foo foo) { _d = foo; }
|
||||
|
||||
const Foo& get_class_ref() const { return _e; }
|
||||
void set_class_ref( const Foo& foo ) { _e = foo; }
|
||||
|
||||
pair<T1,T2> get_template_value() const { return _f; }
|
||||
void set_template_value( const pair<T1,T2> f ) { _f = f; }
|
||||
|
||||
const pair<T1,T2>& get_template_ref() const { return _g; }
|
||||
void set_template_ref( const pair<T1,T2>& g ) { _g = g; }
|
||||
|
||||
std::string get_string() { return str; }
|
||||
void set_string(std::string other) { str = other; }
|
||||
|
||||
private:
|
||||
int _a;
|
||||
int _b;
|
||||
int _c;
|
||||
Foo _d;
|
||||
Foo _e;
|
||||
pair<T1,T2> _f;
|
||||
pair<T1,T2> _g;
|
||||
|
||||
std::string str;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
%define %instantiate_C( T1, T2 )
|
||||
%template (pair_ ## T1 ## T2 ) pair<T1,T2>;
|
||||
// Primitive types
|
||||
%attribute( %arg(C<T1,T2>), int, a, get_value, set_value );
|
||||
%attributeref( %arg(C<T1,T2>), int, b, get_ref );
|
||||
|
||||
// Strings
|
||||
%attributestring(%arg(C<T1,T2>), std::string, str, get_string, set_string);
|
||||
|
||||
// Class types
|
||||
%attributeval( %arg(C<T1,T2>), Foo, d, get_class_value, set_class_value );
|
||||
%attribute2( %arg(C<T1,T2>), Foo, e, get_class_ref, set_class_ref );
|
||||
|
||||
// Moderately templated types
|
||||
%attributeval( %arg(C<T1,T2>), %arg(pair<T1,T2>), f, get_template_value, set_template_value );
|
||||
%attribute2( %arg(C<T1,T2>), %arg(pair<T1,T2>), g, get_template_ref, set_template_ref );
|
||||
|
||||
%template (C ## T1 ## T2) C<T1,T2>;
|
||||
%enddef
|
||||
|
||||
|
||||
%instantiate_C(int,int);
|
||||
67
Examples/test-suite/python/li_attribute_template_runme.py
Normal file
67
Examples/test-suite/python/li_attribute_template_runme.py
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# Check usage of template attributes
|
||||
|
||||
import li_attribute_template
|
||||
|
||||
chell = li_attribute_template.Cintint(1,2,3)
|
||||
|
||||
def rassert( what, master ):
|
||||
if what != master:
|
||||
print what
|
||||
raise RuntimeError
|
||||
|
||||
## Testing primitive by value attribute
|
||||
rassert( chell.a, 1 )
|
||||
|
||||
chell.a = 3
|
||||
rassert( chell.a, 3 )
|
||||
|
||||
## Testing primitive by ref attribute
|
||||
|
||||
rassert( chell.b, 2 )
|
||||
|
||||
chell.b = 5
|
||||
rassert( chell.b,5 )
|
||||
|
||||
## Testing string
|
||||
chell.str = "abc"
|
||||
rassert( chell.str, "abc" )
|
||||
|
||||
# Testing class by value
|
||||
|
||||
rassert( chell.d.value, 1 )
|
||||
|
||||
chell.d = li_attribute_template.Foo(2)
|
||||
rassert( chell.d.value, 2 )
|
||||
|
||||
# Testing class by reference
|
||||
|
||||
rassert( chell.e.value, 2 )
|
||||
|
||||
chell.e= li_attribute_template.Foo(3)
|
||||
rassert( chell.e.value, 3 )
|
||||
|
||||
chell.e.value = 4
|
||||
rassert( chell.e.value, 4 )
|
||||
|
||||
# Testing moderately complex template by value
|
||||
rassert( chell.f.first, 1 )
|
||||
rassert( chell.f.second, 2 )
|
||||
|
||||
pair = li_attribute_template.pair_intint(3,4)
|
||||
chell.f = pair
|
||||
rassert( chell.f.first, 3 )
|
||||
rassert( chell.f.second, 4 )
|
||||
|
||||
# Testing moderately complex template by ref
|
||||
rassert( chell.g.first, 2 )
|
||||
rassert( chell.g.second, 3 )
|
||||
|
||||
pair = li_attribute_template.pair_intint(4,5)
|
||||
chell.g = pair
|
||||
rassert( chell.g.first, 4 )
|
||||
rassert( chell.g.second, 5 )
|
||||
|
||||
chell.g.first = 6
|
||||
chell.g.second = 7
|
||||
rassert( chell.g.first, 6 )
|
||||
rassert( chell.g.second, 7 )
|
||||
|
|
@ -195,42 +195,42 @@
|
|||
|
||||
%define %attribute(Class, AttributeType, AttributeName, GetMethod, SetMethod...)
|
||||
#if #SetMethod != ""
|
||||
%attribute_custom(%arg(Class), AttributeType, AttributeName, GetMethod, SetMethod, self_->GetMethod(), self_->SetMethod(val_))
|
||||
%attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, GetMethod, SetMethod, self_->GetMethod(), self_->SetMethod(val_))
|
||||
#else
|
||||
%attribute_readonly(%arg(Class), AttributeType, AttributeName, GetMethod, self_->GetMethod())
|
||||
%attribute_readonly(%arg(Class), %arg(AttributeType), AttributeName, GetMethod, self_->GetMethod())
|
||||
#endif
|
||||
%enddef
|
||||
|
||||
%define %attribute2(Class, AttributeType, AttributeName, GetMethod, SetMethod...)
|
||||
#if #SetMethod != ""
|
||||
%attribute_custom(%arg(Class), AttributeType, AttributeName, GetMethod, SetMethod, &self_->GetMethod(), self_->SetMethod(*val_))
|
||||
%attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, GetMethod, SetMethod, &self_->GetMethod(), self_->SetMethod(*val_))
|
||||
#else
|
||||
%attribute_readonly(%arg(Class), AttributeType, AttributeName, GetMethod, &self_->GetMethod())
|
||||
%attribute_readonly(%arg(Class), %arg(AttributeType), AttributeName, GetMethod, &self_->GetMethod())
|
||||
#endif
|
||||
%enddef
|
||||
|
||||
%define %attributeref(Class, AttributeType, AttributeName, AccessorMethod...)
|
||||
#if #AccessorMethod != ""
|
||||
%attribute_custom(%arg(Class), AttributeType, AttributeName, AccessorMethod, AccessorMethod, self_->AccessorMethod(), self_->AccessorMethod() = val_)
|
||||
%attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AccessorMethod, AccessorMethod, self_->AccessorMethod(), self_->AccessorMethod() = val_)
|
||||
#else
|
||||
%attribute_custom(%arg(Class), AttributeType, AttributeName, AttributeName, AttributeName, self_->AttributeName(), self_->AttributeName() = val_)
|
||||
%attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AttributeName, AttributeName, self_->AttributeName(), self_->AttributeName() = val_)
|
||||
#endif
|
||||
%enddef
|
||||
|
||||
%define %attribute2ref(Class, AttributeType, AttributeName, AccessorMethod...)
|
||||
#if #AccessorMethod != ""
|
||||
%attribute_custom(%arg(Class), AttributeType, AttributeName, AccessorMethod, AccessorMethod, &self_->AccessorMethod(), self_->AccessorMethod() = *val_)
|
||||
%attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AccessorMethod, AccessorMethod, &self_->AccessorMethod(), self_->AccessorMethod() = *val_)
|
||||
#else
|
||||
%attribute_custom(%arg(Class), AttributeType, AccessorName, AccessorName, AccessorName, &self_->AccessorName(), self_->AccessorName() = *val_)
|
||||
%attribute_custom(%arg(Class), %arg(AttributeType), AccessorName, AccessorName, AccessorName, &self_->AccessorName(), self_->AccessorName() = *val_)
|
||||
#endif
|
||||
%enddef
|
||||
|
||||
// deprecated (same as %attributeref, but there is an argument order inconsistency)
|
||||
%define %attribute_ref(Class, AttributeType, AccessorMethod, AttributeName...)
|
||||
#if #AttributeName != ""
|
||||
%attribute_custom(%arg(Class), AttributeType, AttributeName, AccessorMethod, AccessorMethod, self_->AccessorMethod(), self_->AccessorMethod() = val_)
|
||||
%attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AccessorMethod, AccessorMethod, self_->AccessorMethod(), self_->AccessorMethod() = val_)
|
||||
#else
|
||||
%attribute_custom(%arg(Class), AttributeType, AccessorMethod, AccessorMethod, AccessorMethod, self_->AccessorMethod(), self_->AccessorMethod() = val_)
|
||||
%attribute_custom(%arg(Class), %arg(AttributeType), AccessorMethod, AccessorMethod, AccessorMethod, self_->AccessorMethod(), self_->AccessorMethod() = val_)
|
||||
#endif
|
||||
%enddef
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue