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