1 /* -----------------------------------------------------------------------------
2 * cpointer.i
3 *
4 * D-specific version of ../cpointer.i.
5 * ----------------------------------------------------------------------------- */
6
7 /* -----------------------------------------------------------------------------
8 * %pointer_class(type,name)
9 *
10 * Places a simple proxy around a simple type like 'int', 'float', or whatever.
11 * The proxy provides this interface:
12 *
13 * class type {
14 * public:
15 * type();
16 * ~type();
17 * type value();
18 * void assign(type value);
19 * };
20 *
21 * Example:
22 *
23 * %pointer_class(int, intp);
24 *
25 * int add(int *x, int *y) { return *x + *y; }
26 *
27 * In python (with proxies)
28 *
29 * >>> a = intp()
30 * >>> a.assign(10)
31 * >>> a.value()
32 * 10
33 * >>> b = intp()
34 * >>> b.assign(20)
35 * >>> print add(a,b)
36 * 30
37 *
38 * As a general rule, this macro should not be used on class/structures that
39 * are already defined in the interface.
40 * ----------------------------------------------------------------------------- */
41
42
43 %define %pointer_class(TYPE, NAME)
44 %{
45 typedef TYPE NAME;
46 %}
47
48 typedef struct {
49 } NAME;
50
51 %extend NAME {
52 #ifdef __cplusplus
NAME()53 NAME() {
54 return new TYPE();
55 }
~NAME()56 ~NAME() {
57 if (self) delete self;
58 }
59 #else
60 NAME() {
61 return (TYPE *) calloc(1,sizeof(TYPE));
62 }
63 ~NAME() {
64 if (self) free(self);
65 }
66 #endif
67 }
68
69 %extend NAME {
70
assign(TYPE value)71 void assign(TYPE value) {
72 *self = value;
73 }
value()74 TYPE value() {
75 return *self;
76 }
ptr()77 TYPE * ptr() {
78 return self;
79 }
frompointer(TYPE * t)80 static NAME * frompointer(TYPE *t) {
81 return (NAME *) t;
82 }
83
84 }
85
86 %types(NAME = TYPE);
87
88 %enddef
89
90 /* -----------------------------------------------------------------------------
91 * %pointer_functions(type,name)
92 *
93 * Create functions for allocating/deallocating pointers. This can be used
94 * if you don't want to create a proxy class or if the pointer is complex.
95 *
96 * %pointer_functions(int, intp)
97 *
98 * int add(int *x, int *y) { return *x + *y; }
99 *
100 * In python (with proxies)
101 *
102 * >>> a = copy_intp(10)
103 * >>> intp_value(a)
104 * 10
105 * >>> b = new_intp()
106 * >>> intp_assign(b,20)
107 * >>> print add(a,b)
108 * 30
109 * >>> delete_intp(a)
110 * >>> delete_intp(b)
111 *
112 * ----------------------------------------------------------------------------- */
113
114 %define %pointer_functions(TYPE,NAME)
115 %{
NAME()116 static TYPE *new_##NAME() { %}
117 #ifdef __cplusplus
118 %{ return new TYPE(); %}
119 #else
120 %{ return (TYPE *) calloc(1,sizeof(TYPE)); %}
121 #endif
122 %{}
123
NAME(TYPE value)124 static TYPE *copy_##NAME(TYPE value) { %}
125 #ifdef __cplusplus
126 %{ return new TYPE(value); %}
127 #else
128 %{ TYPE *self = (TYPE *) calloc(1,sizeof(TYPE));
129 *self = value;
130 return self; %}
131 #endif
132 %{}
133
NAME(TYPE * self)134 static void delete_##NAME(TYPE *self) { %}
135 #ifdef __cplusplus
136 %{ if (self) delete self; %}
137 #else
138 %{ if (self) free(self); %}
139 #endif
140 %{}
141
_assign(TYPE * self,TYPE value)142 static void NAME ##_assign(TYPE *self, TYPE value) {
143 *self = value;
144 }
145
_value(TYPE * self)146 static TYPE NAME ##_value(TYPE *self) {
147 return *self;
148 }
149 %}
150
151 TYPE *new_##NAME();
152 TYPE *copy_##NAME(TYPE value);
153 void delete_##NAME(TYPE *self);
154 void NAME##_assign(TYPE *self, TYPE value);
155 TYPE NAME##_value(TYPE *self);
156
157 %enddef
158
159 /* -----------------------------------------------------------------------------
160 * %pointer_cast(type1,type2,name)
161 *
162 * Generates a pointer casting function.
163 * ----------------------------------------------------------------------------- */
164
165 %define %pointer_cast(TYPE1,TYPE2,NAME)
166 %inline %{
NAME(TYPE1 x)167 TYPE2 NAME(TYPE1 x) {
168 return (TYPE2) x;
169 }
170 %}
171 %enddef
172