diff --git a/Examples/test-suite/li_attribute.i b/Examples/test-suite/li_attribute.i new file mode 100644 index 000000000..08957dd65 --- /dev/null +++ b/Examples/test-suite/li_attribute.i @@ -0,0 +1,75 @@ +%module li_attribute + +%include attribute.i + +%attribute(A, int, a, get_a, set_a); +%attribute_ref(A, int, b); + +%attribute_ref(Param, int, value); + + +%attribute(A, int, c, get_c); /* read-only */ +%attribute_ref(A, int, b, d); /* different attribute name 'd' */ + +%inline +{ + struct A + { + A(int a, int b, int c) : _a(a), _b(b), _c(c) + { + } + + int get_a() const + { + return _a; + } + + void set_a(int aa) + { + _a = aa; + } + + const int& b() const + { + return _b; + } + + int& b() + { + return _b; + } + + int get_c() const + { + return _c; + } + private: + int _a; + int _b; + int _c; + }; + + template + struct Param + { + Param(C v) : _v(v) + { + } + + const int& value() const + { + return _v; + } + + int& value() + { + return _v; + } + private: + C _v; + }; +} + +%template(Param_i) Param; + + diff --git a/Examples/test-suite/perl5/Makefile.in b/Examples/test-suite/perl5/Makefile.in index d6b54f353..8e58d0f97 100644 --- a/Examples/test-suite/perl5/Makefile.in +++ b/Examples/test-suite/perl5/Makefile.in @@ -11,6 +11,7 @@ top_builddir = @top_builddir@ CPP_TEST_CASES += \ primitive_types \ + li_attribute \ li_cstring \ C_TEST_CASES += \ diff --git a/Examples/test-suite/python/.cvsignore b/Examples/test-suite/python/.cvsignore index 305aa7c74..9f5d12dab 100644 --- a/Examples/test-suite/python/.cvsignore +++ b/Examples/test-suite/python/.cvsignore @@ -1,7 +1,6 @@ *wrap* *.pyc *.so *.dll *.exp *.lib Makefile argcargvtest.py -attributetest.py autodoc.py callback.py complextest.py @@ -459,3 +458,5 @@ inherit.py empty.py virtual_derivation.py langobj.py +li_attribute.py +typedef_struct.py diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in index 3717d9fa9..dcc9da2e8 100644 --- a/Examples/test-suite/python/Makefile.in +++ b/Examples/test-suite/python/Makefile.in @@ -13,7 +13,6 @@ top_builddir = @top_builddir@ CPP_TEST_CASES += \ argcargvtest \ - attributetest \ autodoc \ callback \ complextest \ @@ -25,6 +24,7 @@ CPP_TEST_CASES += \ input \ inplaceadd \ kwargs \ + li_attribute \ li_cstring \ li_cwstring \ li_implicit \ diff --git a/Examples/test-suite/python/attributetest_runme.py b/Examples/test-suite/python/li_attribute_runme.py similarity index 83% rename from Examples/test-suite/python/attributetest_runme.py rename to Examples/test-suite/python/li_attribute_runme.py index cdcac18e4..cce50af03 100644 --- a/Examples/test-suite/python/attributetest_runme.py +++ b/Examples/test-suite/python/li_attribute_runme.py @@ -1,6 +1,6 @@ -import attributetest +import li_attribute -aa = attributetest.A(1,2,3) +aa = li_attribute.A(1,2,3) if aa.a != 1: raise RuntimeError @@ -28,7 +28,7 @@ if aa.c != 3: #if aa.c != 3: # raise RuntimeError -pi = attributetest.Param_i(7) +pi = li_attribute.Param_i(7) if pi.value != 7: raise RuntimeError diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in index b9f4fd83c..e01235e2e 100644 --- a/Examples/test-suite/ruby/Makefile.in +++ b/Examples/test-suite/ruby/Makefile.in @@ -11,7 +11,13 @@ top_builddir = @top_builddir@ CPP_TEST_CASES = \ track_objects \ - track_objects_directors + track_objects_directors \ + primitive_types \ + li_attribute \ + li_cstring + +C_TEST_CASES += \ + li_cstring include $(srcdir)/../common.mk @@ -43,6 +49,6 @@ run_testcase = \ # Clean %.clean: - + clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile ruby_clean diff --git a/Examples/test-suite/tcl/Makefile.in b/Examples/test-suite/tcl/Makefile.in index 52761e955..dee7d1577 100644 --- a/Examples/test-suite/tcl/Makefile.in +++ b/Examples/test-suite/tcl/Makefile.in @@ -11,6 +11,7 @@ top_builddir = @top_builddir@ CPP_TEST_CASES += \ primitive_types \ + li_attribute \ li_cstring \ li_cwstring \ li_std_wstring diff --git a/Lib/perl5/attribute.i b/Lib/perl5/attribute.i new file mode 100644 index 000000000..779716cd2 --- /dev/null +++ b/Lib/perl5/attribute.i @@ -0,0 +1 @@ +%include diff --git a/Lib/python/attribute.i b/Lib/python/attribute.i index 99dd2a3f1..779716cd2 100644 --- a/Lib/python/attribute.i +++ b/Lib/python/attribute.i @@ -1,152 +1 @@ -%{ -#include -%} - -%include - -/* - Attribute implementation using JOHN E LENZ ideas. - - 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 - like in: - - %attribute(A, int, a, get_a, set_a); - - struct A - { - int get_a() const - { - return _a; - } - - void set_a(int aa) - { - _a = aa; - } - }; - - If you don't provide a 'set' method, a 'read-only' attribute - is generated, ie, like in: - - %attribute(A, int, c, get_c); - - - Use %attribute_ref when you have const/non-const reference - access methods, like in: - - %attribute_ref(A, int, b); - - struct A - { - const int& b() const - { - return _b; - } - - int& b() - { - return _b; - } - }; - - You can also use - - %attribute_ref(class, type, refname, attr); - - if the internal C++ reference methods have a different name from the - attribute you want. - - Then you can use the instances like: - - x = A() - x.a = 3 # calls A::set_a - print x.a # calls A::get_a - - x.b = 3 # calls A::b() - print x.b # calls A::b() const - - NOTE: remember that if the type contains commas, such as - 'std::pair', you need to use the macro like: - - %attribute_ref(A, %arg(std::pair), pval); - - where %arg() 'normalize' the type to be understood as a single - argument, otherwise the macro will get confused (see the 'cpp' - documentation). - -*/ - -#ifdef __cplusplus -%define %_attribute(Class, Wrap, type, attr, getcode, setcode) -%extend Class { - type attr; -} -%{ - template inline - type Wrap ##_## attr ## _get(const C* _t) - { return getcode; } - - template inline - void Wrap ##_## attr ## _set(C* _t, type _val) - { setcode; } -%} -%enddef - -#else - -%define %_attribute(Class, Wrap, type, attr, getcode, setcode) -%extend Class { - type attr; -} -%{ -#define Wrap ##_## attr ## _get(_t) getcode -#define Wrap ##_## attr ## _set(_t, _val) setcode -%} -%enddef -#endif -// -// Internal versions, need Wrap name -// - -%define %attribute_T(Class, Wrap, type, attr, get, ...) -%ignore Class::get; -#if #__VA_ARGS__ != "" - %ignore Class::__VA_ARGS__; - %_attribute(%arg(Class), Wrap, %arg(type), - attr, _t->get(), _t->__VA_ARGS__(_val)) -#else - %_attribute(%arg(Class), Wrap, %arg(type), - attr, _t->get(), - fprintf(stderr,"'attr' is a read-only attribute")) -#endif -%enddef - -%define %_attribute_ref_T(Class, Wrap, type, refname, attr) -%ignore Class::refname(); -%ignore Class::refname() const; -%_attribute(%arg(Class), Wrap, %arg(type), - attr, _t->refname(), _t->refname() = _val) -%enddef - -%define %attribute_ref_T(Class, Wrap, type, refname, ...) -#if #__VA_ARGS__ == "" - %_attribute_ref_T(%arg(Class), Wrap, %arg(type), refname, refname) -#else - %_attribute_ref_T(%arg(Class), Wrap, %arg(type), refname, __VA_ARGS__) -#endif -%enddef - -// -// User versions -// - -%define %attribute(Class, type, attr, get, ...) - %attribute_T(%arg(Class), %mangle(Class), %arg(type), attr, get, __VA_ARGS__) -%enddef - -%define %attribute_ref(Class, type, refname, ...) - %attribute_ref_T(%arg(Class), %mangle(Class), %arg(type), refname, __VA_ARGS__) -%enddef +%include diff --git a/Lib/ruby/attribute.i b/Lib/ruby/attribute.i new file mode 100644 index 000000000..779716cd2 --- /dev/null +++ b/Lib/ruby/attribute.i @@ -0,0 +1 @@ +%include diff --git a/Lib/tcl/attribute.i b/Lib/tcl/attribute.i new file mode 100644 index 000000000..779716cd2 --- /dev/null +++ b/Lib/tcl/attribute.i @@ -0,0 +1 @@ +%include diff --git a/Lib/typemaps/attribute.swg b/Lib/typemaps/attribute.swg new file mode 100644 index 000000000..7480bfc7d --- /dev/null +++ b/Lib/typemaps/attribute.swg @@ -0,0 +1,156 @@ +%{ +#include +%} + +%include + +/* + Attribute implementation using JOHN E LENZ ideas. + + 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 + like in: + + %attribute(A, int, a, get_a, set_a); + + struct A + { + int get_a() const + { + return _a; + } + + void set_a(int aa) + { + _a = aa; + } + }; + + If you don't provide a 'set' method, a 'read-only' attribute + is generated, ie, like in: + + %attribute(A, int, c, get_c); + + + Use %attribute_ref when you have const/non-const reference + access methods, like in: + + %attribute_ref(A, int, b); + + struct A + { + const int& b() const + { + return _b; + } + + int& b() + { + return _b; + } + }; + + You can also use + + %attribute_ref(class, type, refname, attr); + + if the internal C++ reference methods have a different name from the + attribute you want. + + Then you can use the instances like: + + x = A() + x.a = 3 # calls A::set_a + print x.a # calls A::get_a + + x.b = 3 # calls A::b() + print x.b # calls A::b() const + + NOTE: remember that if the type contains commas, such as + 'std::pair', you need to use the macro like: + + %attribute_ref(A, %arg(std::pair), pval); + + where %arg() 'normalize' the type to be understood as a single + argument, otherwise the macro will get confused (see the 'cpp' + documentation). + +*/ + +#ifdef __cplusplus +%define %_attribute(Class, Wrap, type, attr, getcode, setcode) +%extend Class { + type attr; +} +%{ + template inline + type Wrap ##_## attr ## _get(const C* _t) + { return getcode; } + + template inline + type Wrap ##_## attr ## _get(C* _t) + { return getcode; } + + template inline + void Wrap ##_## attr ## _set(C* _t, type _val) + { setcode; } +%} +%enddef + +#else + +%define %_attribute(Class, Wrap, type, attr, getcode, setcode) +%extend Class { + type attr; +} +%{ +#define Wrap ##_## attr ## _get(_t) getcode +#define Wrap ##_## attr ## _set(_t, _val) setcode +%} +%enddef +#endif +// +// Internal versions, need Wrap name +// + +%define %attribute_T(Class, Wrap, type, attr, get, _Type...) +%ignore Class::get; +#if #_Type != "" + %ignore Class::_Type; + %_attribute(%arg(Class), Wrap, %arg(type), + attr, _t->get(), _t->_Type(_val)) +#else + %_attribute(%arg(Class), Wrap, %arg(type), + attr, _t->get(), + fprintf(stderr,"'attr' is a read-only attribute")) +#endif +%enddef + +%define %_attribute_ref_T(Class, Wrap, type, refname, attr) +%ignore Class::refname(); +%ignore Class::refname() const; +%_attribute(%arg(Class), Wrap, %arg(type), + attr, _t->refname(), _t->refname() = _val) +%enddef + +%define %attribute_ref_T(Class, Wrap, type, refname, _Type...) +#if #_Type == "" + %_attribute_ref_T(%arg(Class), Wrap, %arg(type), refname, refname) +#else + %_attribute_ref_T(%arg(Class), Wrap, %arg(type), refname, _Type) +#endif +%enddef + +// +// User versions +// + +%define %attribute(Class, type, attr, get, _Type...) + %attribute_T(%arg(Class), %mangle(Class), %arg(type), attr, get, _Type) +%enddef + +%define %attribute_ref(Class, type, refname, _Type...) + %attribute_ref_T(%arg(Class), %mangle(Class), %arg(type), refname, _Type) +%enddef