Add %attributeval and %attributestring to attribute.swg library
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11128 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
9be7fe899d
commit
589eb8e509
6 changed files with 261 additions and 15 deletions
|
|
@ -1,6 +1,12 @@
|
||||||
Version 1.3.39 (in progress)
|
Version 1.3.39 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
2008-02-14: wsfulton
|
||||||
|
Extend attribute library support for structs/classes and the accessor functions use
|
||||||
|
pass/return by value semantics. Two new macros are available and usage is identical
|
||||||
|
to %attribute. These are %attributeval for structs/classes and %attributestring for
|
||||||
|
string classes, like std::string. See attribute.swg for more details.
|
||||||
|
|
||||||
2008-02-13: wsfulton
|
2008-02-13: wsfulton
|
||||||
Add support for %extend and memberin typemaps. Previously the memberin typemaps were
|
Add support for %extend and memberin typemaps. Previously the memberin typemaps were
|
||||||
ignored for member variables within a %extend block.
|
ignored for member variables within a %extend block.
|
||||||
|
|
|
||||||
78
Examples/test-suite/csharp/li_attribute_runme.cs
Normal file
78
Examples/test-suite/csharp/li_attribute_runme.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
// Ported from Python li_attribute_runme.py
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using li_attributeNamespace;
|
||||||
|
|
||||||
|
public class li_attribute_runme {
|
||||||
|
|
||||||
|
public static void Main() {
|
||||||
|
A aa = new A(1,2,3);
|
||||||
|
|
||||||
|
if (aa.a != 1)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
aa.a = 3;
|
||||||
|
if (aa.a != 3)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
|
||||||
|
if (aa.b != 2)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
aa.b = 5;
|
||||||
|
if (aa.b != 5)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
|
||||||
|
if (aa.d != aa.b)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
|
||||||
|
if (aa.c != 3)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
//aa.c = 5;
|
||||||
|
//if (aa.c != 3)
|
||||||
|
// throw new ApplicationException("error");
|
||||||
|
|
||||||
|
Param_i pi = new Param_i(7);
|
||||||
|
if (pi.value != 7)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
|
||||||
|
pi.value=3;
|
||||||
|
if (pi.value != 3)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
|
||||||
|
B b = new B(aa);
|
||||||
|
|
||||||
|
if (b.a.c != 3)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
|
||||||
|
// class/struct attribute with get/set methods using return/pass by reference
|
||||||
|
MyFoo myFoo = new MyFoo();
|
||||||
|
myFoo.x = 8;
|
||||||
|
MyClass myClass = new MyClass();
|
||||||
|
myClass.Foo = myFoo;
|
||||||
|
if (myClass.Foo.x != 8)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
|
||||||
|
// class/struct attribute with get/set methods using return/pass by value
|
||||||
|
MyClassVal myClassVal = new MyClassVal();
|
||||||
|
if (myClassVal.ReadWriteFoo.x != -1)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
if (myClassVal.ReadOnlyFoo.x != -1)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
myClassVal.ReadWriteFoo = myFoo;
|
||||||
|
if (myClassVal.ReadWriteFoo.x != 8)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
if (myClassVal.ReadOnlyFoo.x != 8)
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
|
||||||
|
// string attribute with get/set methods using return/pass by value
|
||||||
|
MyStringyClass myStringClass = new MyStringyClass("initial string");
|
||||||
|
if (myStringClass.ReadWriteString != "initial string")
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
if (myStringClass.ReadOnlyString != "initial string")
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
myStringClass.ReadWriteString = "changed string";
|
||||||
|
if (myStringClass.ReadWriteString != "changed string")
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
if (myStringClass.ReadOnlyString != "changed string")
|
||||||
|
throw new ApplicationException("error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -93,9 +93,11 @@ struct MyFoo; // %attribute2 does not work with templates
|
||||||
%template(Param_i) Param<int>;
|
%template(Param_i) Param<int>;
|
||||||
|
|
||||||
|
|
||||||
|
// class/struct attribute with get/set methods using return/pass by reference
|
||||||
%attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
|
%attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
|
||||||
%inline %{
|
%inline %{
|
||||||
struct MyFoo {
|
struct MyFoo {
|
||||||
|
MyFoo() : x(-1) {}
|
||||||
int x;
|
int x;
|
||||||
};
|
};
|
||||||
class MyClass {
|
class MyClass {
|
||||||
|
|
@ -106,3 +108,32 @@ struct MyFoo; // %attribute2 does not work with templates
|
||||||
};
|
};
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
// class/struct attribute with get/set methods using return/pass by value
|
||||||
|
%attributeval(MyClassVal, MyFoo, ReadWriteFoo, GetFoo, SetFoo);
|
||||||
|
%attributeval(MyClassVal, MyFoo, ReadOnlyFoo, GetFoo);
|
||||||
|
%inline %{
|
||||||
|
class MyClassVal {
|
||||||
|
MyFoo foo;
|
||||||
|
public:
|
||||||
|
MyFoo GetFoo() { return foo; }
|
||||||
|
void SetFoo(MyFoo other) { foo = other; }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
// string attribute with get/set methods using return/pass by value
|
||||||
|
%include <std_string.i>
|
||||||
|
%attributestring(MyStringyClass, std::string, ReadWriteString, GetString, SetString);
|
||||||
|
%attributestring(MyStringyClass, std::string, ReadOnlyString, GetString);
|
||||||
|
%inline %{
|
||||||
|
class MyStringyClass {
|
||||||
|
std::string str;
|
||||||
|
public:
|
||||||
|
MyStringyClass(const std::string &val) : str(val) {}
|
||||||
|
std::string GetString() { return str; }
|
||||||
|
void SetString(std::string other) { str = other; }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ if (aa.a != 3)
|
||||||
error("aa.a = %i",aa.a)
|
error("aa.a = %i",aa.a)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
if (aa.b != 2)
|
if (aa.b != 2)
|
||||||
error(aa.b)
|
error(aa.b)
|
||||||
endif
|
endif
|
||||||
|
|
@ -19,8 +18,6 @@ if (aa.b != 5)
|
||||||
error
|
error
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (aa.d != aa.b)
|
if (aa.d != aa.b)
|
||||||
error
|
error
|
||||||
endif
|
endif
|
||||||
|
|
@ -39,14 +36,13 @@ if (pi.value != 3)
|
||||||
error
|
error
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
b = li_attribute.B(aa);
|
b = li_attribute.B(aa);
|
||||||
|
|
||||||
if (b.a.c != 3)
|
if (b.a.c != 3)
|
||||||
error
|
error
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
# class/struct attribute with get/set methods using return/pass by reference
|
||||||
myFoo = li_attribute.MyFoo();
|
myFoo = li_attribute.MyFoo();
|
||||||
myFoo.x = 8;
|
myFoo.x = 8;
|
||||||
myClass = li_attribute.MyClass();
|
myClass = li_attribute.MyClass();
|
||||||
|
|
@ -55,3 +51,35 @@ if (myClass.Foo.x != 8)
|
||||||
error
|
error
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# class/struct attribute with get/set methods using return/pass by value
|
||||||
|
myClassVal = li_attribute.MyClassVal();
|
||||||
|
if (myClassVal.ReadWriteFoo.x != -1)
|
||||||
|
error
|
||||||
|
endif
|
||||||
|
if (myClassVal.ReadOnlyFoo.x != -1)
|
||||||
|
error
|
||||||
|
endif
|
||||||
|
myClassVal.ReadWriteFoo = myFoo;
|
||||||
|
if (myClassVal.ReadWriteFoo.x != 8)
|
||||||
|
error
|
||||||
|
endif
|
||||||
|
if (myClassVal.ReadOnlyFoo.x != 8)
|
||||||
|
error
|
||||||
|
endif
|
||||||
|
|
||||||
|
# string attribute with get/set methods using return/pass by value
|
||||||
|
myStringyClass = li_attribute.MyStringyClass("initial string");
|
||||||
|
if (myStringyClass.ReadWriteString != "initial string")
|
||||||
|
error
|
||||||
|
endif
|
||||||
|
if (myStringyClass.ReadOnlyString != "initial string")
|
||||||
|
error
|
||||||
|
endif
|
||||||
|
myStringyClass.ReadWriteString = "changed string";
|
||||||
|
if (myStringyClass.ReadWriteString != "changed string")
|
||||||
|
error
|
||||||
|
endif
|
||||||
|
if (myStringyClass.ReadOnlyString != "changed string")
|
||||||
|
error
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# Ported to C# li_attribute_runme.cs
|
||||||
|
|
||||||
import li_attribute
|
import li_attribute
|
||||||
|
|
||||||
aa = li_attribute.A(1,2,3)
|
aa = li_attribute.A(1,2,3)
|
||||||
|
|
@ -9,7 +11,6 @@ if aa.a != 3:
|
||||||
print aa.a
|
print aa.a
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
||||||
if aa.b != 2:
|
if aa.b != 2:
|
||||||
print aa.b
|
print aa.b
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
@ -17,8 +18,6 @@ aa.b = 5
|
||||||
if aa.b != 5:
|
if aa.b != 5:
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if aa.d != aa.b:
|
if aa.d != aa.b:
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
@ -36,17 +35,40 @@ pi.value=3
|
||||||
if pi.value != 3:
|
if pi.value != 3:
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
||||||
b = li_attribute.B(aa)
|
b = li_attribute.B(aa)
|
||||||
|
|
||||||
if b.a.c != 3:
|
if b.a.c != 3:
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
|
# class/struct attribute with get/set methods using return/pass by reference
|
||||||
myFoo = li_attribute.MyFoo
|
myFoo = li_attribute.MyFoo()
|
||||||
myFoo.x = 8
|
myFoo.x = 8
|
||||||
myClass = li_attribute.MyClass
|
myClass = li_attribute.MyClass()
|
||||||
myClass.Foo = myFoo
|
myClass.Foo = myFoo
|
||||||
if myClass.Foo.x != 8:
|
if myClass.Foo.x != 8:
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
|
# class/struct attribute with get/set methods using return/pass by value
|
||||||
|
myClassVal = li_attribute.MyClassVal()
|
||||||
|
if myClassVal.ReadWriteFoo.x != -1:
|
||||||
|
raise RuntimeError
|
||||||
|
if myClassVal.ReadOnlyFoo.x != -1:
|
||||||
|
raise RuntimeError
|
||||||
|
myClassVal.ReadWriteFoo = myFoo
|
||||||
|
if myClassVal.ReadWriteFoo.x != 8:
|
||||||
|
raise RuntimeError
|
||||||
|
if myClassVal.ReadOnlyFoo.x != 8:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
# string attribute with get/set methods using return/pass by value
|
||||||
|
myStringyClass = li_attribute.MyStringyClass("initial string")
|
||||||
|
if myStringyClass.ReadWriteString != "initial string":
|
||||||
|
raise RuntimeError
|
||||||
|
if myStringyClass.ReadOnlyString != "initial string":
|
||||||
|
raise RuntimeError
|
||||||
|
myStringyClass.ReadWriteString = "changed string"
|
||||||
|
if myStringyClass.ReadWriteString != "changed string":
|
||||||
|
raise RuntimeError
|
||||||
|
if myStringyClass.ReadOnlyString != "changed string":
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
The following macros convert a pair of set/get methods
|
The following macros convert a pair of set/get methods
|
||||||
into a "native" attribute.
|
into a "native" attribute.
|
||||||
|
|
||||||
Use %attribute when you have a pair of get/set methods
|
Use %attribute when you have a pair of get/set methods to a primitive type
|
||||||
like in:
|
like in:
|
||||||
|
|
||||||
%attribute(A, int, a, get_a, set_a);
|
%attribute(A, int, a, get_a, set_a);
|
||||||
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
%attribute(A, int, c, get_c);
|
%attribute(A, int, c, get_c);
|
||||||
|
|
||||||
Use %attributeref when you have const/non-const reference
|
Use %attributeref when you have const/non-const reference access methods
|
||||||
access methods, like in:
|
for primitive types or class/structs, like in:
|
||||||
|
|
||||||
%attributeref(A, int, b);
|
%attributeref(A, int, b);
|
||||||
|
|
||||||
|
|
@ -99,6 +99,40 @@
|
||||||
|
|
||||||
where %arg() 'normalizes' the type to be understood as a single
|
where %arg() 'normalizes' the type to be understood as a single
|
||||||
argument, otherwise the macro will get confused by the comma.
|
argument, otherwise the macro will get confused by the comma.
|
||||||
|
|
||||||
|
The %attributeval is the same as %attribute, but should be used when the type
|
||||||
|
is a class/struct (ie a non-primitive type) and when the get and set methods
|
||||||
|
return/pass by value. The following is very similar to the above example, but
|
||||||
|
note that the access is by value rather than reference.
|
||||||
|
|
||||||
|
%attributeval(MyClassVal, MyFoo, ReadWriteFoo, GetFoo, SetFoo);
|
||||||
|
%attributeval(MyClassVal, MyFoo, ReadOnlyFoo, GetFoo);
|
||||||
|
%inline %{
|
||||||
|
class MyClassVal {
|
||||||
|
MyFoo foo;
|
||||||
|
public:
|
||||||
|
MyFoo GetFoo() { return foo; }
|
||||||
|
void SetFoo(MyFoo other) { foo = other; }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
The %attributestring is the same as %attributeval, but should be used for string
|
||||||
|
class types, which are unusual as they are a class on the C++ side, but normally an
|
||||||
|
immutable/primitive type in the target language. Example usage for std::string:
|
||||||
|
|
||||||
|
%include <std_string.i>
|
||||||
|
%attributestring(MyStringyClass, std::string, ReadWriteString, GetString, SetString);
|
||||||
|
%attributestring(MyStringyClass, std::string, ReadOnlyString, GetString);
|
||||||
|
%inline %{
|
||||||
|
class MyStringyClass {
|
||||||
|
std::string str;
|
||||||
|
public:
|
||||||
|
MyStringyClass(const std::string &val) : str(val) {}
|
||||||
|
std::string GetString() { return str; }
|
||||||
|
void SetString(std::string other) { str = other; }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -203,3 +237,50 @@
|
||||||
#endif
|
#endif
|
||||||
%enddef
|
%enddef
|
||||||
|
|
||||||
|
|
||||||
|
%define %attributeval(Class, AttributeType, AttributeName, GetMethod, SetMethod...)
|
||||||
|
%{
|
||||||
|
#define %mangle(Class) ##_## AttributeName ## _get(self_) new AttributeType(self_->GetMethod())
|
||||||
|
%}
|
||||||
|
#if #SetMethod != ""
|
||||||
|
%{
|
||||||
|
#define %mangle(Class) ##_## AttributeName ## _set(self_, val_) self_->SetMethod(*val_)
|
||||||
|
%}
|
||||||
|
#if #SetMethod != #AttributeName
|
||||||
|
%ignore Class::SetMethod;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
%immutable Class::AttributeName;
|
||||||
|
#endif
|
||||||
|
%ignore Class::GetMethod();
|
||||||
|
%ignore Class::GetMethod() const;
|
||||||
|
%newobject Class::AttributeName;
|
||||||
|
%extend Class {
|
||||||
|
AttributeType AttributeName;
|
||||||
|
}
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
|
||||||
|
%define %attributestring(Class, AttributeType, AttributeName, GetMethod, SetMethod...)
|
||||||
|
%{
|
||||||
|
#define %mangle(Class) ##_## AttributeName ## _get(self_) *new AttributeType(self_->GetMethod())
|
||||||
|
%}
|
||||||
|
#if #SetMethod != ""
|
||||||
|
%{
|
||||||
|
#define %mangle(Class) ##_## AttributeName ## _set(self_, val_) self_->SetMethod(val_)
|
||||||
|
%}
|
||||||
|
#if #SetMethod != #AttributeName
|
||||||
|
%ignore Class::SetMethod;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
%immutable Class::AttributeName;
|
||||||
|
#endif
|
||||||
|
%ignore Class::GetMethod();
|
||||||
|
%ignore Class::GetMethod() const;
|
||||||
|
%newobject Class::AttributeName;
|
||||||
|
%typemap(newfree) const AttributeType &AttributeName "delete $1;// my newfree override"
|
||||||
|
%extend Class {
|
||||||
|
AttributeType AttributeName;
|
||||||
|
}
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue