PageRenderTime 23ms CodeModel.GetById 13ms app.highlight 5ms RepoModel.GetById 2ms app.codeStats 0ms

/tags/rel-1-3-29/SWIG/Lib/tcl/std_vector.i

#
Swig | 422 lines | 372 code | 40 blank | 10 comment | 0 complexity | cfd7d58fa02637ab545dee455228d01b MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1/* -----------------------------------------------------------------------------
  2 * See the LICENSE file for information on copyright, usage and redistribution
  3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
  4 *
  5 * std_vector.i
  6 * ----------------------------------------------------------------------------- */
  7
  8%include <std_common.i>
  9
 10// ------------------------------------------------------------------------
 11// std::vector
 12// 
 13// The aim of all that follows would be to integrate std::vector with 
 14// Tcl as much as possible, namely, to allow the user to pass and 
 15// be returned Tcl lists.
 16// const declarations are used to guess the intent of the function being
 17// exported; therefore, the following rationale is applied:
 18// 
 19//   -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*):
 20//      the parameter being read-only, either a Tcl list or a
 21//      previously wrapped std::vector<T> can be passed.
 22//   -- f(std::vector<T>&), f(std::vector<T>*):
 23//      the parameter must be modified; therefore, only a wrapped std::vector
 24//      can be passed.
 25//   -- std::vector<T> f():
 26//      the vector is returned by copy; therefore, a Tcl list of T:s 
 27//      is returned which is most easily used in other Tcl functions procs
 28//   -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(),
 29//      const std::vector<T>* f():
 30//      the vector is returned by reference; therefore, a wrapped std::vector
 31//      is returned
 32// ------------------------------------------------------------------------
 33
 34%{
 35#include <vector>
 36#include <algorithm>
 37#include <stdexcept>
 38#include <string>
 39
 40Tcl_Obj* SwigString_FromString(std::string s) {
 41    return Tcl_NewStringObj(s.c_str(), s.length());
 42}
 43
 44int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
 45  int v;
 46  int res = Tcl_GetBooleanFromObj(interp, o, &v);
 47  if (res == TCL_OK) {
 48    *val = v ? true : false;
 49  }
 50  return res;  
 51}
 52 
 53int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
 54    int len;
 55    const char* temp = Tcl_GetStringFromObj(o, &len);
 56    if(temp == NULL)
 57        return TCL_ERROR;
 58    *val = temp;
 59    return TCL_OK;
 60}
 61
 62// behaviour of this is such as the real Tcl_GetIntFromObj
 63template <typename Type>
 64int SwigInt_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) {
 65    int temp_val, return_val;
 66    return_val = Tcl_GetIntFromObj(interp, o, &temp_val);
 67    *val = (Type) temp_val;
 68    return return_val;
 69}
 70
 71// behaviour of this is such as the real Tcl_GetDoubleFromObj
 72template <typename Type>
 73int SwigDouble_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) {
 74    int return_val;
 75    double temp_val;
 76    return_val = Tcl_GetDoubleFromObj(interp, o, &temp_val);
 77    *val = (Type) temp_val;
 78    return return_val;
 79}
 80
 81%}
 82
 83// exported class
 84
 85namespace std {
 86    
 87    template<class T> class vector {
 88        %typemap(in) vector<T> (std::vector<T> *v) {
 89            Tcl_Obj **listobjv;
 90            int       nitems;
 91            int       i;
 92            T*        temp;
 93
 94            if (SWIG_ConvertPtr($input, (void **) &v, \
 95                                $&1_descriptor, 0) == 0){
 96                $1 = *v;
 97            } else {
 98                // It isn't a vector<T> so it should be a list of T's
 99                if(Tcl_ListObjGetElements(interp, $input, \
100                                          &nitems, &listobjv) == TCL_ERROR)
101                    return TCL_ERROR;
102                $1 = std::vector<T>();
103                for (i = 0; i < nitems; i++) {
104                    if ((SWIG_ConvertPtr(listobjv[i],(void **) &temp,
105                                         $descriptor(T *),0)) != 0) {
106                        char message[] = 
107                            "list of " #T " expected";
108                        Tcl_SetResult(interp, message, TCL_VOLATILE);
109                        return TCL_ERROR;
110                    }
111                    $1.push_back(*temp);
112                } 
113            }
114        }
115
116        %typemap(in) const vector<T>* (std::vector<T> *v, std::vector<T> w),
117                     const vector<T>& (std::vector<T> *v, std::vector<T> w) {
118            Tcl_Obj **listobjv;
119            int       nitems;
120            int       i;
121            T*        temp;
122
123            if(SWIG_ConvertPtr($input, (void **) &v, \
124                               $&1_descriptor, 0) == 0) {
125                $1 = v;
126            } else {
127                // It isn't a vector<T> so it should be a list of T's
128                if(Tcl_ListObjGetElements(interp, $input, 
129                                          &nitems, &listobjv) == TCL_ERROR)
130                    return TCL_ERROR;
131                w = std::vector<T>();
132                for (i = 0; i < nitems; i++) {
133                    if ((SWIG_ConvertPtr(listobjv[i],(void **) &temp,
134                                         $descriptor(T *),0)) != 0) {
135                        char message[] = 
136                            "list of " #T " expected";
137                        Tcl_SetResult(interp, message, TCL_VOLATILE);
138                        return TCL_ERROR;
139                    }
140                    w.push_back(*temp);
141                } 
142                $1 = &w;
143            }
144        }
145
146        %typemap(out) vector<T> {
147            for (unsigned int i=0; i<$1.size(); i++) {
148                T* ptr = new T((($1_type &)$1)[i]);
149                Tcl_ListObjAppendElement(interp, $result, \
150                                         SWIG_NewInstanceObj(ptr, 
151                                                             $descriptor(T *), 
152                                                             0));
153            }
154        }
155
156        %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
157            Tcl_Obj **listobjv;
158            int       nitems;
159            T*        temp;
160            std::vector<T> *v;
161            
162            if(SWIG_ConvertPtr($input, (void **) &v, \
163                               $&1_descriptor, 0) == 0) {
164                /* wrapped vector */
165                $1 = 1;
166            } else {
167                // It isn't a vector<T> so it should be a list of T's
168                if(Tcl_ListObjGetElements(interp, $input, 
169                                          &nitems, &listobjv) == TCL_ERROR)
170                    $1 = 0;
171                else
172                    if (nitems == 0)
173                        $1 = 1;
174                //check the first value to see if it is of correct type
175                    else if ((SWIG_ConvertPtr(listobjv[0],
176                                              (void **) &temp, 
177                                              $descriptor(T *),0)) != 0)
178                        $1 = 0;
179                    else
180                        $1 = 1;
181            }
182        }
183        
184        %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
185                                          const vector<T>* {
186            Tcl_Obj **listobjv;
187            int       nitems;
188            T*         temp;
189            std::vector<T> *v;
190
191            if(SWIG_ConvertPtr($input, (void **) &v, \
192                               $1_descriptor, 0) == 0){
193                /* wrapped vector */
194                $1 = 1;
195            } else {
196                // It isn't a vector<T> so it should be a list of T's
197                if(Tcl_ListObjGetElements(interp, $input, 
198                                          &nitems, &listobjv) == TCL_ERROR)
199                    $1 = 0;
200                else
201                    if (nitems == 0)
202                        $1 = 1;
203                //check the first value to see if it is of correct type
204                    else if ((SWIG_ConvertPtr(listobjv[0],
205                                              (void **) &temp,
206                                              $descriptor(T *),0)) != 0)
207                        $1 = 0;
208                    else
209                        $1 = 1;
210            }
211        }
212      
213      public:
214        vector(unsigned int size = 0);
215        vector(unsigned int size, const T& value);
216        vector(const vector<T> &);
217
218        unsigned int size() const;
219        bool empty() const;
220        void clear();
221        %rename(push) push_back;
222        void push_back(const T& x);
223        %extend {
224            T pop() throw (std::out_of_range) {
225                if (self->size() == 0)
226                    throw std::out_of_range("pop from empty vector");
227                T x = self->back();
228                self->pop_back();
229                return x;
230            }
231            T& get(int i) throw (std::out_of_range) {
232                int size = int(self->size());
233                if (i<0) i += size;
234                if (i>=0 && i<size)
235                    return (*self)[i];
236                else
237                    throw std::out_of_range("vector index out of range");
238            }
239            void set(int i, const T& x) throw (std::out_of_range) {
240                int size = int(self->size());
241                if (i<0) i+= size;
242                if (i>=0 && i<size)
243                    (*self)[i] = x;
244                else
245                    throw std::out_of_range("vector index out of range");
246            }
247        }
248    };
249
250
251    // specializations for built-ins
252
253    %define specialize_std_vector(T, CONVERT_FROM, CONVERT_TO)
254    template<> class vector<T> {
255
256        %typemap(in) vector<T> (std::vector<T> *v){
257            Tcl_Obj **listobjv;
258            int       nitems;
259            int       i;
260            T         temp;
261
262            if(SWIG_ConvertPtr($input, (void **) &v, \
263                               $&1_descriptor, 0) == 0) {
264                $1 = *v;
265            } else {
266                // It isn't a vector<T> so it should be a list of T's
267                if(Tcl_ListObjGetElements(interp, $input, 
268                                          &nitems, &listobjv) == TCL_ERROR)
269                    return TCL_ERROR;					      
270                $1 = std::vector<T>();
271                for (i = 0; i < nitems; i++) {
272                    if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR)
273                        return TCL_ERROR;
274                    $1.push_back(temp);
275                } 
276            }
277        }
278      
279        %typemap(in) const vector<T>& (std::vector<T> *v,std::vector<T> w),
280                     const vector<T>* (std::vector<T> *v,std::vector<T> w) {
281            Tcl_Obj **listobjv;
282            int       nitems;
283            int       i;
284            T         temp;
285
286            if(SWIG_ConvertPtr($input, (void **) &v, \
287                               $1_descriptor, 0) == 0) {
288                $1 = v;
289            } else {
290                // It isn't a vector<T> so it should be a list of T's
291                if(Tcl_ListObjGetElements(interp, $input, 
292                                          &nitems, &listobjv) == TCL_ERROR)
293                    return TCL_ERROR;
294                w = std::vector<T>();
295                for (i = 0; i < nitems; i++) {
296                    if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR)
297                        return TCL_ERROR;
298                    w.push_back(temp);
299                } 
300                $1 = &w;
301            }
302        }
303
304        %typemap(out) vector<T> {
305            for (unsigned int i=0; i<$1.size(); i++) {
306                Tcl_ListObjAppendElement(interp, $result, \
307                                         CONVERT_TO((($1_type &)$1)[i]));
308            }
309        }
310       
311        %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
312            Tcl_Obj **listobjv;
313            int       nitems;
314            T         temp;
315            std::vector<T> *v;
316
317            if(SWIG_ConvertPtr($input, (void **) &v, \
318                               $&1_descriptor, 0) == 0){
319                /* wrapped vector */
320                $1 = 1;
321            } else {
322                // It isn't a vector<T> so it should be a list of T's
323                if(Tcl_ListObjGetElements(interp, $input, 
324                                          &nitems, &listobjv) == TCL_ERROR)
325                    $1 = 0;
326                else
327                    if (nitems == 0)
328                        $1 = 1;
329                //check the first value to see if it is of correct type
330                if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
331                    $1 = 0;
332                else
333                    $1 = 1;
334            }
335        }      
336
337        %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
338	                                      const vector<T>*{
339            Tcl_Obj **listobjv;
340            int       nitems;
341            T         temp;
342            std::vector<T> *v;
343
344            if(SWIG_ConvertPtr($input, (void **) &v, \
345                               $1_descriptor, 0) == 0){
346                /* wrapped vector */
347                $1 = 1;
348            } else {
349                // It isn't a vector<T> so it should be a list of T's
350                if(Tcl_ListObjGetElements(interp, $input, 
351                                          &nitems, &listobjv) == TCL_ERROR)
352                    $1 = 0;
353                else
354                    if (nitems == 0)
355                        $1 = 1;
356                //check the first value to see if it is of correct type
357                if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
358                    $1 = 0;
359                else
360                    $1 = 1;
361            }
362        }
363        
364      public:
365        vector(unsigned int size = 0);
366        vector(unsigned int size, const T& value);
367        vector(const vector<T> &);
368
369        unsigned int size() const;
370        bool empty() const;
371        void clear();
372        %rename(push) push_back;
373        void push_back(T x);
374        %extend {
375            T pop() throw (std::out_of_range) {
376                if (self->size() == 0)
377                    throw std::out_of_range("pop from empty vector");
378                T x = self->back();
379                self->pop_back();
380                return x;
381            }
382            T get(int i) throw (std::out_of_range) {
383                int size = int(self->size());
384                if (i<0) i += size;
385                if (i>=0 && i<size)
386                    return (*self)[i];
387                else
388                    throw std::out_of_range("vector index out of range");
389            }
390            void set(int i, T x) throw (std::out_of_range) {
391                int size = int(self->size());
392                if (i<0) i+= size;
393                if (i>=0 && i<size)
394                    (*self)[i] = x;
395                else
396                    throw std::out_of_range("vector index out of range");
397            }
398        }
399    };
400    %enddef
401
402    specialize_std_vector(bool, Tcl_GetBoolFromObj, Tcl_NewBooleanObj);
403    specialize_std_vector(char, SwigInt_As<char>,Tcl_NewIntObj);
404    specialize_std_vector(int, Tcl_GetIntFromObj,Tcl_NewIntObj);
405    specialize_std_vector(short, SwigInt_As<short>, Tcl_NewIntObj);
406    specialize_std_vector(long, SwigInt_As<long>, Tcl_NewIntObj);
407    specialize_std_vector(unsigned char, 
408                          SwigInt_As<unsigned char>, Tcl_NewIntObj);
409    specialize_std_vector(unsigned int, 
410                          SwigInt_As<unsigned int>, Tcl_NewIntObj);
411    specialize_std_vector(unsigned short, 
412                          SwigInt_As<unsigned short>, Tcl_NewIntObj);
413    specialize_std_vector(unsigned long, 
414                          SwigInt_As<unsigned long>, Tcl_NewIntObj);
415    specialize_std_vector(double, Tcl_GetDoubleFromObj, Tcl_NewDoubleObj);
416    specialize_std_vector(float, SwigDouble_As<float>, Tcl_NewDoubleObj);
417    specialize_std_vector(std::string, 
418                          SwigString_AsString, SwigString_FromString);
419
420}
421
422