PageRenderTime 17ms CodeModel.GetById 2ms app.highlight 7ms RepoModel.GetById 2ms app.codeStats 0ms

/trunk/Lib/perl5/std_list.i

#
Swig | 365 lines | 328 code | 16 blank | 21 comment | 0 complexity | 975d25628fa9aa42355e83a6de59cd69 MD5 | raw file
  1/* -----------------------------------------------------------------------------
  2 * std_list.i
  3 *
  4 * SWIG typemaps for std::list types
  5 * ----------------------------------------------------------------------------- */
  6
  7%include <std_common.i>
  8%include <exception.i>
  9
 10// containers
 11
 12
 13// ------------------------------------------------------------------------
 14// std::list
 15// 
 16// The aim of all that follows would be to integrate std::list with 
 17// Perl as much as possible, namely, to allow the user to pass and 
 18// be returned Perl arrays.
 19// const declarations are used to guess the intent of the function being
 20// exported; therefore, the following rationale is applied:
 21// 
 22//   -- f(std::list<T>), f(const std::list<T>&), f(const std::list<T>*):
 23//      the parameter being read-only, either a Perl sequence or a
 24//      previously wrapped std::list<T> can be passed.
 25//   -- f(std::list<T>&), f(std::list<T>*):
 26//      the parameter must be modified; therefore, only a wrapped std::list
 27//      can be passed.
 28//   -- std::list<T> f():
 29//      the list is returned by copy; therefore, a Perl sequence of T:s 
 30//      is returned which is most easily used in other Perl functions
 31//   -- std::list<T>& f(), std::list<T>* f(), const std::list<T>& f(),
 32//      const std::list<T>* f():
 33//      the list is returned by reference; therefore, a wrapped std::list
 34//      is returned
 35// ------------------------------------------------------------------------
 36
 37%{
 38#include <list>
 39#include <algorithm>
 40#include <stdexcept>
 41%}
 42
 43// exported class
 44
 45namespace std {
 46    
 47    template<class T> class list {
 48        %typemap(in) list<T> (std::list<T>* v) {
 49            if (SWIG_ConvertPtr($input,(void **) &v, 
 50                                $&1_descriptor,1) != -1) {
 51                $1 = *v;
 52            } else if (SvROK($input)) {
 53                AV *av = (AV *)SvRV($input);
 54                if (SvTYPE(av) != SVt_PVAV)
 55                    SWIG_croak("Type error in argument $argnum of $symname. "
 56                               "Expected an array of " #T);
 57                SV **tv;
 58                I32 len = av_len(av) + 1;
 59                T* obj;
 60                for (int i=0; i<len; i++) {
 61                    tv = av_fetch(av, i, 0);
 62                    if (SWIG_ConvertPtr(*tv, (void **)&obj, 
 63                                        $descriptor(T *),0) != -1) {
 64                        $1.push_back(*obj);
 65                    } else {
 66                        SWIG_croak("Type error in argument $argnum of "
 67                                   "$symname. "
 68                                   "Expected an array of " #T);
 69                    }
 70                }
 71            } else {
 72                SWIG_croak("Type error in argument $argnum of $symname. "
 73                           "Expected an array of " #T);
 74            }
 75        }
 76        %typemap(in) const list<T>& (std::list<T> temp,
 77                                       std::list<T>* v),
 78                     const list<T>* (std::list<T> temp,
 79                                       std::list<T>* v) {
 80            if (SWIG_ConvertPtr($input,(void **) &v, 
 81                                $1_descriptor,1) != -1) {
 82                $1 = v;
 83            } else if (SvROK($input)) {
 84                AV *av = (AV *)SvRV($input);
 85                if (SvTYPE(av) != SVt_PVAV)
 86                    SWIG_croak("Type error in argument $argnum of $symname. "
 87                               "Expected an array of " #T);
 88                SV **tv;
 89                I32 len = av_len(av) + 1;
 90                T* obj;
 91                for (int i=0; i<len; i++) {
 92                    tv = av_fetch(av, i, 0);
 93                    if (SWIG_ConvertPtr(*tv, (void **)&obj, 
 94                                        $descriptor(T *),0) != -1) {
 95                        temp.push_back(*obj);
 96                    } else {
 97                        SWIG_croak("Type error in argument $argnum of "
 98                                   "$symname. "
 99                                   "Expected an array of " #T);
100                    }
101                }
102                $1 = &temp;
103            } else {
104                SWIG_croak("Type error in argument $argnum of $symname. "
105                           "Expected an array of " #T);
106            }
107        }
108        %typemap(out) list<T> {
109	    std::list<T>::const_iterator i;
110            unsigned int j;
111            int len = $1.size();
112            SV **svs = new SV*[len];
113            for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
114                T* ptr = new T(*i);
115                svs[j] = sv_newmortal();
116                SWIG_MakePtr(svs[j], (void*) ptr, 
117                             $descriptor(T *), $shadow|$owner);
118            }
119            AV *myav = av_make(len, svs);
120            delete[] svs;
121            $result = newRV_noinc((SV*) myav);
122            sv_2mortal($result);
123            argvi++;
124        }
125        %typecheck(SWIG_TYPECHECK_LIST) list<T> {
126            {
127                /* wrapped list? */
128                std::list<T >* v;
129                if (SWIG_ConvertPtr($input,(void **) &v, 
130                                    $1_&descriptor,0) != -1) {
131                    $1 = 1;
132                } else if (SvROK($input)) {
133                    /* native sequence? */
134                    AV *av = (AV *)SvRV($input);
135                    if (SvTYPE(av) == SVt_PVAV) {
136                        SV **tv;
137                        I32 len = av_len(av) + 1;
138                        if (len == 0) {
139                            /* an empty sequence can be of any type */
140                            $1 = 1;
141                        } else {
142                            /* check the first element only */
143                            T* obj;
144                            tv = av_fetch(av, 0, 0);
145                            if (SWIG_ConvertPtr(*tv, (void **)&obj, 
146                                                $descriptor(T *),0) != -1)
147                                $1 = 1;
148                            else
149                                $1 = 0;
150                        }
151                    }
152                } else {
153                    $1 = 0;
154                }
155            }
156        }
157        %typecheck(SWIG_TYPECHECK_LIST) const list<T>&,
158                                          const list<T>* {
159            {
160                /* wrapped list? */
161                std::list<T >* v;
162                if (SWIG_ConvertPtr($input,(void **) &v, 
163                                    $1_descriptor,0) != -1) {
164                    $1 = 1;
165                } else if (SvROK($input)) {
166                    /* native sequence? */
167                    AV *av = (AV *)SvRV($input);
168                    if (SvTYPE(av) == SVt_PVAV) {
169                        SV **tv;
170                        I32 len = av_len(av) + 1;
171                        if (len == 0) {
172                            /* an empty sequence can be of any type */
173                            $1 = 1;
174                        } else {
175                            /* check the first element only */
176                            T* obj;
177                            tv = av_fetch(av, 0, 0);
178                            if (SWIG_ConvertPtr(*tv, (void **)&obj, 
179                                                $descriptor(T *),0) != -1)
180                                $1 = 1;
181                            else
182                                $1 = 0;
183                        }
184                    }
185                } else {
186                    $1 = 0;
187                }
188            }
189        }
190      public:
191        list();
192        list(const list<T> &);
193
194        unsigned int size() const;
195        bool empty() const;
196        void clear();
197        %rename(push) push_back;
198        void push_back(const T& x);
199    };
200
201
202    // specializations for built-ins
203
204    %define specialize_std_list(T,CHECK_T,TO_T,FROM_T)
205    template<> class list<T> {
206        %typemap(in) list<T> (std::list<T>* v) {
207            if (SWIG_ConvertPtr($input,(void **) &v, 
208                                $&1_descriptor,1) != -1){
209                $1 = *v;
210            } else if (SvROK($input)) {
211                AV *av = (AV *)SvRV($input);
212                if (SvTYPE(av) != SVt_PVAV)
213                    SWIG_croak("Type error in argument $argnum of $symname. "
214                               "Expected an array of " #T);
215                SV **tv;
216                I32 len = av_len(av) + 1;
217                for (int i=0; i<len; i++) {
218                    tv = av_fetch(av, i, 0);
219                    if (CHECK_T(*tv)) {
220                        $1.push_back(TO_T(*tv));
221                    } else {
222                        SWIG_croak("Type error in argument $argnum of "
223                                   "$symname. "
224                                   "Expected an array of " #T);
225                    }
226                }
227            } else {
228                SWIG_croak("Type error in argument $argnum of $symname. "
229                           "Expected an array of " #T);
230            }
231        }
232        %typemap(in) const list<T>& (std::list<T> temp,
233                                       std::list<T>* v),
234                     const list<T>* (std::list<T> temp,
235                                       std::list<T>* v) {
236            if (SWIG_ConvertPtr($input,(void **) &v, 
237                                $1_descriptor,1) != -1) {
238                $1 = v;
239            } else if (SvROK($input)) {
240                AV *av = (AV *)SvRV($input);
241                if (SvTYPE(av) != SVt_PVAV)
242                    SWIG_croak("Type error in argument $argnum of $symname. "
243                               "Expected an array of " #T);
244                SV **tv;
245                I32 len = av_len(av) + 1;
246                T* obj;
247                for (int i=0; i<len; i++) {
248                    tv = av_fetch(av, i, 0);
249                    if (CHECK_T(*tv)) {
250                        temp.push_back(TO_T(*tv));
251                    } else {
252                        SWIG_croak("Type error in argument $argnum of "
253                                   "$symname. "
254                                   "Expected an array of " #T);
255                    }
256                }
257                $1 = &temp;
258            } else {
259                SWIG_croak("Type error in argument $argnum of $symname. "
260                           "Expected an array of " #T);
261            }
262        }
263        %typemap(out) list<T> {
264	    std::list<T>::const_iterator i;
265            unsigned int j;
266            int len = $1.size();
267            SV **svs = new SV*[len];
268            for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
269                svs[j] = sv_newmortal();
270                FROM_T(svs[j], *i);
271            }
272            AV *myav = av_make(len, svs);
273            delete[] svs;
274            $result = newRV_noinc((SV*) myav);
275            sv_2mortal($result);
276            argvi++;
277        }
278        %typecheck(SWIG_TYPECHECK_LIST) list<T> {
279            {
280                /* wrapped list? */
281                std::list<T >* v;
282                if (SWIG_ConvertPtr($input,(void **) &v, 
283                                    $1_&descriptor,0) != -1) {
284                    $1 = 1;
285                } else if (SvROK($input)) {
286                    /* native sequence? */
287                    AV *av = (AV *)SvRV($input);
288                    if (SvTYPE(av) == SVt_PVAV) {
289                        SV **tv;
290                        I32 len = av_len(av) + 1;
291                        if (len == 0) {
292                            /* an empty sequence can be of any type */
293                            $1 = 1;
294                        } else {
295                            /* check the first element only */
296                            tv = av_fetch(av, 0, 0);
297                            if (CHECK_T(*tv))
298                                $1 = 1;
299                            else
300                                $1 = 0;
301                        }
302                    }
303                } else {
304                    $1 = 0;
305                }
306            }
307        }
308        %typecheck(SWIG_TYPECHECK_LIST) const list<T>&,
309                                          const list<T>* {
310            {
311                /* wrapped list? */
312                std::list<T >* v;
313                if (SWIG_ConvertPtr($input,(void **) &v, 
314                                    $1_descriptor,0) != -1) {
315                    $1 = 1;
316                } else if (SvROK($input)) {
317                    /* native sequence? */
318                    AV *av = (AV *)SvRV($input);
319                    if (SvTYPE(av) == SVt_PVAV) {
320                        SV **tv;
321                        I32 len = av_len(av) + 1;
322                        if (len == 0) {
323                            /* an empty sequence can be of any type */
324                            $1 = 1;
325                        } else {
326                            /* check the first element only */
327                            tv = av_fetch(av, 0, 0);
328                            if (CHECK_T(*tv))
329                                $1 = 1;
330                            else
331                                $1 = 0;
332                        }
333                    }
334                } else {
335                    $1 = 0;
336                }
337            }
338        }
339      public:
340        list();
341        list(const list<T> &);
342
343        unsigned int size() const;
344        bool empty() const;
345        void clear();
346        %rename(push) push_back;
347        void push_back(T x);
348    };
349    %enddef
350
351    specialize_std_list(bool,SvIOK,SvIVX,sv_setiv);
352    specialize_std_list(char,SvIOK,SvIVX,sv_setiv);
353    specialize_std_list(int,SvIOK,SvIVX,sv_setiv);
354    specialize_std_list(short,SvIOK,SvIVX,sv_setiv);
355    specialize_std_list(long,SvIOK,SvIVX,sv_setiv);
356    specialize_std_list(unsigned char,SvIOK,SvIVX,sv_setiv);
357    specialize_std_list(unsigned int,SvIOK,SvIVX,sv_setiv);
358    specialize_std_list(unsigned short,SvIOK,SvIVX,sv_setiv);
359    specialize_std_list(unsigned long,SvIOK,SvIVX,sv_setiv);
360    specialize_std_list(float,SvNIOK,SwigSvToNumber,sv_setnv);
361    specialize_std_list(double,SvNIOK,SwigSvToNumber,sv_setnv);
362    specialize_std_list(std::string,SvPOK,SvPVX,SwigSvFromString);
363
364}
365