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)
|
||||
============================
|
||||
|
||||
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
|
||||
Add support for %extend and memberin typemaps. Previously the memberin typemaps were
|
||||
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>;
|
||||
|
||||
|
||||
// class/struct attribute with get/set methods using return/pass by reference
|
||||
%attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
|
||||
%inline %{
|
||||
struct MyFoo {
|
||||
MyFoo() : x(-1) {}
|
||||
int x;
|
||||
};
|
||||
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)
|
||||
endif
|
||||
|
||||
|
||||
if (aa.b != 2)
|
||||
error(aa.b)
|
||||
endif
|
||||
|
|
@ -19,8 +18,6 @@ if (aa.b != 5)
|
|||
error
|
||||
endif
|
||||
|
||||
|
||||
|
||||
if (aa.d != aa.b)
|
||||
error
|
||||
endif
|
||||
|
|
@ -39,14 +36,13 @@ if (pi.value != 3)
|
|||
error
|
||||
endif
|
||||
|
||||
|
||||
b = li_attribute.B(aa);
|
||||
|
||||
if (b.a.c != 3)
|
||||
error
|
||||
endif
|
||||
|
||||
|
||||
# class/struct attribute with get/set methods using return/pass by reference
|
||||
myFoo = li_attribute.MyFoo();
|
||||
myFoo.x = 8;
|
||||
myClass = li_attribute.MyClass();
|
||||
|
|
@ -55,3 +51,35 @@ if (myClass.Foo.x != 8)
|
|||
error
|
||||
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
|
||||
|
||||
aa = li_attribute.A(1,2,3)
|
||||
|
|
@ -9,7 +11,6 @@ if aa.a != 3:
|
|||
print aa.a
|
||||
raise RuntimeError
|
||||
|
||||
|
||||
if aa.b != 2:
|
||||
print aa.b
|
||||
raise RuntimeError
|
||||
|
|
@ -17,8 +18,6 @@ aa.b = 5
|
|||
if aa.b != 5:
|
||||
raise RuntimeError
|
||||
|
||||
|
||||
|
||||
if aa.d != aa.b:
|
||||
raise RuntimeError
|
||||
|
||||
|
|
@ -36,17 +35,40 @@ pi.value=3
|
|||
if pi.value != 3:
|
||||
raise RuntimeError
|
||||
|
||||
|
||||
b = li_attribute.B(aa)
|
||||
|
||||
if b.a.c != 3:
|
||||
raise RuntimeError
|
||||
|
||||
|
||||
myFoo = li_attribute.MyFoo
|
||||
# class/struct attribute with get/set methods using return/pass by reference
|
||||
myFoo = li_attribute.MyFoo()
|
||||
myFoo.x = 8
|
||||
myClass = li_attribute.MyClass
|
||||
myClass = li_attribute.MyClass()
|
||||
myClass.Foo = myFoo
|
||||
if myClass.Foo.x != 8:
|
||||
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
|
||||
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:
|
||||
|
||||
%attribute(A, int, a, get_a, set_a);
|
||||
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
%attribute(A, int, c, get_c);
|
||||
|
||||
Use %attributeref when you have const/non-const reference
|
||||
access methods, like in:
|
||||
Use %attributeref when you have const/non-const reference access methods
|
||||
for primitive types or class/structs, like in:
|
||||
|
||||
%attributeref(A, int, b);
|
||||
|
||||
|
|
@ -99,6 +99,40 @@
|
|||
|
||||
where %arg() 'normalizes' the type to be understood as a single
|
||||
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
|
||||
%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