1 /***************************************************************************
2                           convert2.cpp  -  convert one datatype into another
3                              -------------------
4     begin                : July 22 2002
5     copyright            : (C) 2002 by Marc Schellens
6     email                : m_schellens@users.sf.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 // TODO: adjust the with for string conversion for each type (i2s((*this)[i],X))
19 
20 // Convert2( DType) functions
21 
22 #include "includefirst.hpp"
23 
24 //#include "datatypes.hpp"
25 #include "dstructgdl.hpp"
26 #include "real2int.hpp"
27 #include "ofmt.hpp" // OutAuto
28 
29 #include "dinterpreter.hpp"
30 
31 using namespace std;
32 
33 //#define TRACE_CONVERT2 cout << "Convert2 " << this->TypeStr() << " -> " << destTy << "\tn " << dd.size() << "\tmode " << mode << endl;
34 #define TRACE_CONVERT2
35 
36 #define DO_CONVERT_START(tnew)  {bool dopar=(CpuTPOOL_NTHREADS >1 && nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl));\
37         Data_<tnew>* dest=new Data_<tnew>( dim, BaseGDL::NOZERO);\
38         if( nEl == 1) { (*dest)[0]=(*this)[0]; if( (mode & BaseGDL::CONVERT) != 0) delete this; return dest;}\
39         if(!dopar) {for( SizeT i=0; i < nEl; ++i) (*dest)[i]=(*this)[i]; if( (mode & BaseGDL::CONVERT) != 0) delete this; return dest; }
40 
41 #define DO_CONVERT_START_CPX(tnew)  {bool dopar=(CpuTPOOL_NTHREADS >1 && nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl));\
42         Data_<tnew>* dest=new Data_<tnew>( dim, BaseGDL::NOZERO);\
43         if( nEl == 1) { (*dest)[0]=(*this)[0].real(); if( (mode & BaseGDL::CONVERT) != 0) delete this; return dest;}\
44         if(!dopar) {for( SizeT i=0; i < nEl; ++i) (*dest)[i]=(*this)[i].real(); if( (mode & BaseGDL::CONVERT) != 0) delete this; return dest; }
45 
46 #define DO_CONVERT_END 	for( SizeT i=0; i < nEl; ++i) (*dest)[i]=(*this)[i]; if( (mode & BaseGDL::CONVERT) != 0) delete this; return dest; }
47 #define DO_CONVERT_END_CPX 	for( SizeT i=0; i < nEl; ++i) (*dest)[i]=(*this)[i].real(); if( (mode & BaseGDL::CONVERT) != 0) delete this; return dest; }
48 
49 // for double -> string
double2string(const DDouble d)50 inline string double2string( const DDouble d)
51 {
52   std::ostringstream os;
53   OutAuto( os, d, 16, 8, 0);
54   return os.str();
55 }
56 
57 // for float -> string
float2string(const DFloat f)58 inline string float2string( const DFloat f)
59 {
60   std::ostringstream os;
61   OutAuto( os, f, 13, 6, 0);
62   return os.str();
63 }
64 
65 // for string -> float/double
66 template <typename real_t>
67 inline real_t string2real_helper(const char* cStart, char** cEnd);
68 
69 template <>
string2real_helper(const char * cStart,char ** cEnd)70 inline float string2real_helper<float>(const char* cStart, char** cEnd)
71 {
72 #ifdef _MSC_VER
73   return StrToD(cStart, cEnd);
74 #else
75   return strtof(cStart, cEnd);
76 #endif
77 }
78 
79 template <>
string2real_helper(const char * cStart,char ** cEnd)80 inline double string2real_helper<double>(const char* cStart, char** cEnd)
81 {
82   return StrToD(cStart, cEnd);
83 }
84 
85 template <typename real_t>
string2real(const char * cStart,char ** cEnd)86 inline real_t string2real(const char* cStart, char** cEnd)
87 {
88   const char* d = strpbrk(cStart, "Dd");
89   if (d == NULL)
90     return string2real_helper<real_t>(cStart, cEnd);
91   else
92   {
93     string tmps(cStart);
94     tmps[d - cStart] = 'E';
95     char* tmpcp;
96     real_t tmpf = string2real_helper<real_t>(tmps.c_str(), &tmpcp);
97     *cEnd = const_cast<char*>(cStart) + (tmpcp - tmps.c_str());
98     return tmpf;
99   }
100 }
101 
102 // every type need this function which defines its conversion to all other types
103 // so for every new type each of this functions has to be extended
104 // and a new function has to be 'specialized'
105 // not very nice, but how else to do?
106 // each function creates the new type on the heap
107 
108 // non convertables
109 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)110 BaseGDL* DStructGDL::Convert2(DType destTy, BaseGDL::Convert2Mode mode)
111 {
112   TRACE_CONVERT2
113   if (destTy == t) return (((mode & BaseGDL::COPY) != 0) ? Dup() : this);
114   //DInterpreter* testDbg = BaseGDL::interpreter;
115   //int szDbg = BaseGDL::interpreter->CallStack().size();
116   if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Struct expression not allowed in this context: " + BaseGDL::interpreter->Name(this));
117   throw GDLException("Struct expression not allowed in this context.");
118   return NULL; // get rid of warning
119 }
120 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)121 template<> BaseGDL* Data_<SpDPtr>::Convert2(DType destTy, BaseGDL::Convert2Mode mode)
122 {
123   TRACE_CONVERT2
124   if (destTy == t) return (((mode & BaseGDL::COPY) != 0) ? Dup() : this);
125   if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Ptr expression not allowed in this context: " + BaseGDL::interpreter->Name(this));
126   throw GDLException("Ptr expression not allowed in this context.");
127   return NULL; // get rid of warning
128 }
129 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)130 template<> BaseGDL* Data_<SpDObj>::Convert2(DType destTy, BaseGDL::Convert2Mode mode)
131 {
132   TRACE_CONVERT2
133   if (destTy == t) return (((mode & BaseGDL::COPY) != 0) ? Dup() : this);
134   if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Object expression not allowed in this context: " + BaseGDL::interpreter->Name(this));
135   throw GDLException("Object expression not allowed in this context.");
136   return NULL; // get rid of warning
137 }
138 
139 // the real Convert2 functions
140 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)141 template<> BaseGDL* Data_<SpDByte>::Convert2(DType destTy, BaseGDL::Convert2Mode mode)
142 {
143   TRACE_CONVERT2
144   if (destTy == t) return (((mode & BaseGDL::COPY) != 0) ? Dup() : this);
145 
146   SizeT nEl = dd.size();
147   switch (destTy) {
148   case GDL_BYTE: return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
149   case GDL_INT:
150     DO_CONVERT_START(SpDInt)
151 #pragma omp parallel for
152         DO_CONVERT_END
153   case GDL_UINT:
154     DO_CONVERT_START(SpDUInt)
155 #pragma omp parallel for
156         DO_CONVERT_END
157   case GDL_LONG:
158     DO_CONVERT_START(SpDLong)
159 #pragma omp parallel for
160         DO_CONVERT_END
161   case GDL_ULONG:
162     DO_CONVERT_START(SpDULong)
163 #pragma omp parallel for
164         DO_CONVERT_END
165   case GDL_LONG64:
166     DO_CONVERT_START(SpDLong64)
167 #pragma omp parallel for
168         DO_CONVERT_END
169   case GDL_ULONG64:
170     DO_CONVERT_START(SpDULong64)
171 #pragma omp parallel for
172         DO_CONVERT_END
173   case GDL_FLOAT:
174     DO_CONVERT_START(SpDFloat)
175 #pragma omp parallel for
176         DO_CONVERT_END
177   case GDL_DOUBLE:
178     DO_CONVERT_START(SpDDouble)
179 #pragma omp parallel for
180         DO_CONVERT_END
181   case GDL_COMPLEX:
182     DO_CONVERT_START(SpDComplex)
183 #pragma omp parallel for
184         DO_CONVERT_END
185   case GDL_COMPLEXDBL:
186     DO_CONVERT_START(SpDComplexDbl)
187 #pragma omp parallel for
188         DO_CONVERT_END
189   case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
190   {
191     if (mode == BaseGDL::COPY_BYTE_AS_INT) {
192       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
193 #pragma omp parallel for
194       for (SizeT i = 0; i < nEl; ++i)
195         (*dest)[i] = i2s(static_cast<int> ((*this)[i]), 4);
196       if ((mode & BaseGDL::CONVERT) != 0) delete this;
197       return dest;
198     } else //NOTE: This should be only for BYTES according to the doc, but IDL in fact does it for all integer types below l64 apparently
199     {
200       dimension strDim(dim);
201       SizeT strLen = strDim.Remove(0);
202 
203       if (strLen == 0) strLen = 1;
204 
205       nEl /= strLen;
206 
207       char *buf = new char[ strLen + 1];
208       ArrayGuard<char> guard(buf);
209 
210       buf[ strLen] = 0;
211       Data_<SpDString>* dest =
212           new Data_<SpDString>(strDim, BaseGDL::NOZERO);
213       for (SizeT i = 0; i < nEl; ++i) {
214         SizeT basePtr = i*strLen;
215         for (SizeT b = 0; b < strLen; b++)
216           buf[b] = (*this)[ basePtr + b];
217 
218         (*dest)[i] = buf; //i2s((*this)[i]);
219       }
220 
221       if ((mode & BaseGDL::CONVERT) != 0) delete this;
222       return dest;
223     }
224   }
225   case GDL_PTR:
226   case GDL_OBJ:
227   case GDL_STRUCT:
228   case GDL_UNDEF:
229   default:
230     if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
231     throw GDLException("Cannot convert to this type.");
232   }
233 
234   return NULL; // get rid of warning
235 } // GDL_BYTE
236 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)237 template<> BaseGDL* Data_<SpDInt>::Convert2(DType destTy, BaseGDL::Convert2Mode mode)
238 {
239   TRACE_CONVERT2
240   if (destTy == t) return (((mode & BaseGDL::COPY) != 0) ? Dup() : this);
241 
242   SizeT nEl = dd.size();
243 
244   switch (destTy) {
245   case GDL_BYTE:
246     DO_CONVERT_START(SpDByte)
247 #pragma omp parallel for
248         DO_CONVERT_END
249   case GDL_INT: return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
250   case GDL_UINT:
251     DO_CONVERT_START(SpDUInt)
252 #pragma omp parallel for
253         DO_CONVERT_END
254   case GDL_LONG:
255     DO_CONVERT_START(SpDLong)
256 #pragma omp parallel for
257         DO_CONVERT_END
258   case GDL_ULONG:
259     DO_CONVERT_START(SpDULong)
260 #pragma omp parallel for
261         DO_CONVERT_END
262   case GDL_LONG64:
263     DO_CONVERT_START(SpDLong64)
264 #pragma omp parallel for
265         DO_CONVERT_END
266   case GDL_ULONG64:
267     DO_CONVERT_START(SpDULong64)
268 #pragma omp parallel for
269         DO_CONVERT_END
270   case GDL_FLOAT:
271     DO_CONVERT_START(SpDFloat)
272 #pragma omp parallel for
273         DO_CONVERT_END
274   case GDL_DOUBLE:
275     DO_CONVERT_START(SpDDouble)
276 #pragma omp parallel for
277         DO_CONVERT_END
278   case GDL_COMPLEX:
279     DO_CONVERT_START(SpDComplex)
280 #pragma omp parallel for
281         DO_CONVERT_END
282   case GDL_COMPLEXDBL:
283     DO_CONVERT_START(SpDComplexDbl)
284 #pragma omp parallel for
285         DO_CONVERT_END
286   case GDL_STRING:
287   {
288     Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
289 #pragma omp parallel for
290     for (SizeT i = 0; i < nEl; ++i) (*dest)[i] = i2s((*this)[i], 8);
291     if ((mode & BaseGDL::CONVERT) != 0) delete this;
292     return dest;
293   }
294   case GDL_PTR:
295   case GDL_OBJ:
296   case GDL_STRUCT:
297   case GDL_UNDEF:
298   default:
299     if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
300     throw GDLException("Cannot convert to this type.");
301   }
302 
303   return NULL; // get rid of warning
304 } // GDL_INT
305 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)306 template<> BaseGDL* Data_<SpDUInt>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
307 {
308   TRACE_CONVERT2
309   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
310 
311   SizeT nEl=dd.size();
312 
313   switch (destTy) {
314   case GDL_BYTE:
315     DO_CONVERT_START(SpDByte)
316 #pragma omp parallel for
317         DO_CONVERT_END
318   case GDL_INT:
319     DO_CONVERT_START(SpDInt)
320 #pragma omp parallel for
321         DO_CONVERT_END
322   case GDL_UINT: return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
323   case GDL_LONG:
324     DO_CONVERT_START(SpDLong)
325 #pragma omp parallel for
326         DO_CONVERT_END
327   case GDL_ULONG:
328     DO_CONVERT_START(SpDULong)
329 #pragma omp parallel for
330         DO_CONVERT_END
331   case GDL_LONG64:
332     DO_CONVERT_START(SpDLong64)
333 #pragma omp parallel for
334         DO_CONVERT_END
335   case GDL_ULONG64:
336     DO_CONVERT_START(SpDULong64)
337 #pragma omp parallel for
338         DO_CONVERT_END
339   case GDL_FLOAT:
340     DO_CONVERT_START(SpDFloat)
341 #pragma omp parallel for
342         DO_CONVERT_END
343   case GDL_DOUBLE:
344     DO_CONVERT_START(SpDDouble)
345 #pragma omp parallel for
346         DO_CONVERT_END
347   case GDL_COMPLEX:
348     DO_CONVERT_START(SpDComplex)
349 #pragma omp parallel for
350         DO_CONVERT_END
351   case GDL_COMPLEXDBL:
352     DO_CONVERT_START(SpDComplexDbl)
353 #pragma omp parallel for
354         DO_CONVERT_END
355   case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
356   {
357     Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
358 #pragma omp parallel for
359     for (SizeT i = 0; i < nEl; ++i) (*dest)[i] = i2s((*this)[i], 8);
360     if ((mode & BaseGDL::CONVERT) != 0) delete this;
361     return dest;
362   }
363     case GDL_PTR:
364     case GDL_OBJ:
365     case GDL_STRUCT:
366     case GDL_UNDEF:
367   default:
368     if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
369     throw GDLException("Cannot convert to this type.");
370   }
371 
372    return NULL; // get rid of warning
373 } // GDL_UINT
374 
375 
376 
377 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)378 template<> BaseGDL* Data_<SpDLong>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
379 {
380 TRACE_CONVERT2
381   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
382 
383   SizeT nEl=dd.size();
384 
385     switch (destTy) {
386     case GDL_BYTE:
387       DO_CONVERT_START(SpDByte)
388 #pragma omp parallel for
389           DO_CONVERT_END
390     case GDL_INT:
391       DO_CONVERT_START(SpDInt)
392 #pragma omp parallel for
393           DO_CONVERT_END
394     case GDL_UINT:
395       DO_CONVERT_START(SpDUInt)
396 #pragma omp parallel for
397           DO_CONVERT_END
398     case GDL_LONG:       return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
399     case GDL_ULONG:
400       DO_CONVERT_START(SpDULong)
401 #pragma omp parallel for
402           DO_CONVERT_END
403     case GDL_LONG64:
404       DO_CONVERT_START(SpDLong64)
405 #pragma omp parallel for
406           DO_CONVERT_END
407     case GDL_ULONG64:
408       DO_CONVERT_START(SpDULong64)
409 #pragma omp parallel for
410           DO_CONVERT_END
411     case GDL_FLOAT:
412       DO_CONVERT_START(SpDFloat)
413 #pragma omp parallel for
414           DO_CONVERT_END
415     case GDL_DOUBLE:
416       DO_CONVERT_START(SpDDouble)
417 #pragma omp parallel for
418           DO_CONVERT_END
419     case GDL_COMPLEX:
420       DO_CONVERT_START(SpDComplex)
421 #pragma omp parallel for
422           DO_CONVERT_END
423     case GDL_COMPLEXDBL:
424       DO_CONVERT_START(SpDComplexDbl)
425 #pragma omp parallel for
426           DO_CONVERT_END
427     case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
428     {
429       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
430 #pragma omp parallel for
431       for (SizeT i = 0; i < nEl; ++i) (*dest)[i] = i2s((*this)[i], 12);
432       if ((mode & BaseGDL::CONVERT) != 0) delete this;
433       return dest;
434     }
435     case GDL_PTR:
436     case GDL_OBJ:
437     case GDL_STRUCT:
438     case GDL_UNDEF:
439     default:
440       if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
441       throw GDLException("Cannot convert to this type.");
442     }
443 
444    // get rid of warning
445   return NULL;
446 } // GDL_LONG
447 
448 
449 
450 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)451 template<> BaseGDL* Data_<SpDULong>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
452 {
453 TRACE_CONVERT2
454   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
455 
456   SizeT nEl=dd.size();
457 
458   switch( destTy) {
459     case GDL_BYTE:
460       DO_CONVERT_START(SpDByte)
461 #pragma omp parallel for
462           DO_CONVERT_END
463     case GDL_INT:
464       DO_CONVERT_START(SpDInt)
465 #pragma omp parallel for
466           DO_CONVERT_END
467     case GDL_UINT:
468       DO_CONVERT_START(SpDUInt)
469 #pragma omp parallel for
470           DO_CONVERT_END
471     case GDL_LONG:
472       DO_CONVERT_START(SpDLong)
473 #pragma omp parallel for
474           DO_CONVERT_END
475   case GDL_ULONG:       return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
476     case GDL_LONG64:
477       DO_CONVERT_START(SpDLong64)
478 #pragma omp parallel for
479           DO_CONVERT_END
480     case GDL_ULONG64:
481       DO_CONVERT_START(SpDULong64)
482 #pragma omp parallel for
483           DO_CONVERT_END
484     case GDL_FLOAT:
485       DO_CONVERT_START(SpDFloat)
486 #pragma omp parallel for
487           DO_CONVERT_END
488     case GDL_DOUBLE:
489       DO_CONVERT_START(SpDDouble)
490 #pragma omp parallel for
491           DO_CONVERT_END
492     case GDL_COMPLEX:
493       DO_CONVERT_START(SpDComplex)
494 #pragma omp parallel for
495           DO_CONVERT_END
496     case GDL_COMPLEXDBL:
497       DO_CONVERT_START(SpDComplexDbl)
498 #pragma omp parallel for
499           DO_CONVERT_END
500     case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
501     {
502       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
503 #pragma omp parallel for
504       for (SizeT i = 0; i < nEl; ++i) (*dest)[i] = i2s((*this)[i], 12);
505       if ((mode & BaseGDL::CONVERT) != 0) delete this;
506       return dest;
507     }
508     case GDL_PTR:
509     case GDL_OBJ:
510     case GDL_STRUCT:
511     case GDL_UNDEF:
512     default:
513       if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
514       throw GDLException("Cannot convert to this type.");
515     }
516 
517    // get rid of warning
518   return NULL;
519 } // GDL_ULONG
520 
521 
522 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)523 template<> BaseGDL* Data_<SpDFloat>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
524 {
525 TRACE_CONVERT2
526   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
527 
528   SizeT nEl=dd.size();
529 
530   switch( destTy) {
531     case GDL_BYTE:
532       DO_CONVERT_START(SpDByte)
533 #pragma omp parallel for
534           DO_CONVERT_END
535     case GDL_INT:
536       DO_CONVERT_START(SpDInt)
537 #pragma omp parallel for
538           DO_CONVERT_END
539     case GDL_UINT:
540       DO_CONVERT_START(SpDUInt)
541 #pragma omp parallel for
542           DO_CONVERT_END
543     case GDL_LONG:
544       DO_CONVERT_START(SpDLong)
545 #pragma omp parallel for
546           DO_CONVERT_END
547   case GDL_ULONG:
548       DO_CONVERT_START(SpDULong)
549 #pragma omp parallel for
550           DO_CONVERT_END
551   case GDL_LONG64:
552       DO_CONVERT_START(SpDLong64)
553 #pragma omp parallel for
554           DO_CONVERT_END
555     case GDL_ULONG64:
556       DO_CONVERT_START(SpDULong64)
557 #pragma omp parallel for
558           DO_CONVERT_END
559     case GDL_FLOAT:      return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
560 
561     case GDL_DOUBLE:
562       DO_CONVERT_START(SpDDouble)
563 #pragma omp parallel for
564           DO_CONVERT_END
565     case GDL_COMPLEX:
566       DO_CONVERT_START(SpDComplex)
567 #pragma omp parallel for
568           DO_CONVERT_END
569     case GDL_COMPLEXDBL:
570       DO_CONVERT_START(SpDComplexDbl)
571 #pragma omp parallel for
572           DO_CONVERT_END
573     case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
574     {
575       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
576 #pragma omp parallel for
577       for (SizeT i = 0; i < nEl; ++i) (*dest)[i]=float2string((*this)[i]);
578       if ((mode & BaseGDL::CONVERT) != 0) delete this;
579       return dest;
580     }
581     case GDL_PTR:
582     case GDL_OBJ:
583     case GDL_STRUCT:
584     case GDL_UNDEF:
585     default:
586       if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
587       throw GDLException("Cannot convert to this type.");
588     }
589 
590 // get rid of warning
591   return NULL;
592 }
593 
594 
595 
596 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)597 template<> BaseGDL* Data_<SpDDouble>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
598 {
599 TRACE_CONVERT2
600   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
601 
602   SizeT nEl=dd.size();
603 
604   switch( destTy) {
605     case GDL_BYTE:
606       DO_CONVERT_START(SpDByte)
607 #pragma omp parallel for
608           DO_CONVERT_END
609     case GDL_INT:
610       DO_CONVERT_START(SpDInt)
611 #pragma omp parallel for
612           DO_CONVERT_END
613     case GDL_UINT:
614       DO_CONVERT_START(SpDUInt)
615 #pragma omp parallel for
616           DO_CONVERT_END
617     case GDL_LONG:
618       DO_CONVERT_START(SpDLong)
619 #pragma omp parallel for
620           DO_CONVERT_END
621   case GDL_ULONG:
622       DO_CONVERT_START(SpDULong)
623 #pragma omp parallel for
624           DO_CONVERT_END
625   case GDL_LONG64:
626       DO_CONVERT_START(SpDLong64)
627 #pragma omp parallel for
628           DO_CONVERT_END
629     case GDL_ULONG64:
630       DO_CONVERT_START(SpDULong64)
631 #pragma omp parallel for
632           DO_CONVERT_END
633     case GDL_FLOAT:
634       DO_CONVERT_START(SpDFloat)
635 #pragma omp parallel for
636           DO_CONVERT_END
637     case GDL_DOUBLE:     return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
638     case GDL_COMPLEX:
639       DO_CONVERT_START(SpDComplex)
640 #pragma omp parallel for
641           DO_CONVERT_END
642     case GDL_COMPLEXDBL:
643       DO_CONVERT_START(SpDComplexDbl)
644 #pragma omp parallel for
645           DO_CONVERT_END
646     case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
647     {
648       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
649 #pragma omp parallel for
650       for (SizeT i = 0; i < nEl; ++i) (*dest)[i]=double2string((*this)[i]);
651       if ((mode & BaseGDL::CONVERT) != 0) delete this;
652       return dest;
653     }
654     case GDL_PTR:
655     case GDL_OBJ:
656     case GDL_STRUCT:
657     case GDL_UNDEF:
658     default:
659       if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
660       throw GDLException("Cannot convert to this type.");
661     }
662 
663    // get rid of warning
664   return NULL;
665 }
666 
667 
668 
669 
670 
StringConversionError(bool & errorFlag,BaseGDL::Convert2Mode mode,const string & msg)671 inline void StringConversionError( bool& errorFlag, BaseGDL::Convert2Mode mode, const string& msg)
672 {
673   if( (mode & BaseGDL::THROWIOERROR) != 0)
674  {
675 	errorFlag = true;
676 /*    delete dest;
677     throw GDLIOException( msg);*/
678   }
679 else
680 	Warning( msg);
681 }
682 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)683 template<> BaseGDL* Data_<SpDString>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
684 {
685 TRACE_CONVERT2
686   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
687 
688   SizeT nEl=dd.size();
689 
690   bool errorFlag = false;
691 
692   switch( destTy)
693     {
694     case GDL_BYTE: // GDL_STRING to GDL_BYTE: add first dim
695       {
696 	SizeT maxLen = 1; // empty string is converted to 0b
697       	for( SizeT i=0; i < nEl; ++i)
698 	  if( (*this)[i].length() > maxLen) maxLen = (*this)[i].length();
699 
700 	dimension bytDim( dim);
701 	bytDim >> maxLen;
702 
703       	Data_<SpDByte>* dest=new Data_<SpDByte>( bytDim); // zero fields
704 TRACEOMP( __FILE__, __LINE__)
705 #pragma omp parallel
706 {
707 #pragma omp for
708       	for( OMPInt i=0; i < nEl; ++i)
709 	  {
710 	    SizeT basePtr = i*maxLen;
711 
712 	    SizeT strLen = (*this)[ i].length();
713 	    for( SizeT b=0; b<strLen; b++)
714 	      (*dest)[basePtr + b] = (*this)[ i][ b];
715  	  }
716 }
717 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
718 	return dest;
719       }
720     case GDL_INT:
721       {
722       	Data_<SpDInt>* dest=new Data_<SpDInt>( dim, BaseGDL::NOZERO);
723  TRACEOMP( __FILE__, __LINE__)
724  #pragma omp parallel shared( errorFlag, mode)
725  {
726  #pragma omp for
727       	for( OMPInt i=0; i < nEl; ++i)
728       	  {
729       	    const char* cStart=(*this)[i].c_str();
730       	    char* cEnd;
731       	    (*dest)[i]=strtol(cStart,&cEnd,10);
732       	    if( cEnd == cStart && (*this)[i] != "")
733       	      {
734 		StringConversionError( errorFlag, mode, "Type conversion error: "
735 				       "Unable to convert given STRING: '"+
736 				       (*this)[i]+"' to INT.");
737       	      }
738 	  }
739  }
740 	if( errorFlag)
741 	{
742 		delete dest;
743 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
744 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to INT.");
745 	}
746 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
747 	return dest;
748       }
749     case GDL_UINT:
750       {
751       	Data_<SpDUInt>* dest=new Data_<SpDUInt>( dim, BaseGDL::NOZERO);
752 TRACEOMP( __FILE__, __LINE__)
753 #pragma omp parallel shared( errorFlag, mode)
754 {
755 #pragma omp for
756       	for( OMPInt i=0; i < nEl; ++i)
757       	  {
758       	    const char* cStart=(*this)[i].c_str();
759       	    char* cEnd;
760       	    (*dest)[i]=strtoul(cStart,&cEnd,10);
761       	    if( cEnd == cStart && (*this)[i] != "")
762       	      {
763 StringConversionError( errorFlag, mode, "Type conversion error: "
764 				       "Unable to convert given STRING: '"+
765 				       (*this)[i]+"' to UINT.");
766       	      }
767       	  }
768 }
769 	if( errorFlag)
770 	{
771 		delete dest;
772 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
773 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to UINT.");
774 	}
775 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
776       	return dest;
777       }
778     case GDL_LONG:
779       {
780       	Data_<SpDLong>* dest=new Data_<SpDLong>( dim, BaseGDL::NOZERO);
781 TRACEOMP( __FILE__, __LINE__)
782 #pragma omp parallel shared( errorFlag, mode)
783 {
784 #pragma omp for
785       	for( OMPInt i=0; i < nEl; ++i)
786       	  {
787       	    const char* cStart=(*this)[i].c_str();
788       	    char* cEnd;
789       	    (*dest)[i]=strtol(cStart,&cEnd,10);
790       	    if( cEnd == cStart && (*this)[i] != "")
791       	      {
792 StringConversionError( errorFlag, mode, "Type conversion error: "
793 				       "Unable to convert given STRING: '"+
794 				       (*this)[i]+"' to LONG.");
795       	      }
796       	  }
797 }
798 	if( errorFlag)
799 	{
800 		delete dest;
801 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
802 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to LONG.");
803 	}
804 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
805       	return dest;
806       }
807     case GDL_ULONG:
808       {
809       	Data_<SpDULong>* dest=new Data_<SpDULong>( dim, BaseGDL::NOZERO);
810 TRACEOMP( __FILE__, __LINE__)
811 #pragma omp parallel shared( errorFlag, mode)
812 {
813 #pragma omp for
814       	for( OMPInt i=0; i < nEl; ++i)
815       	  {
816       	    const char* cStart=(*this)[i].c_str();
817       	    char* cEnd;
818       	    (*dest)[i]=strtoul(cStart,&cEnd,10);
819       	    if( cEnd == cStart && (*this)[i] != "")
820       	      {
821 StringConversionError( errorFlag, mode, "Type conversion error: "
822 				       "Unable to convert given STRING: '"+
823 				       (*this)[i]+"' to ULONG.");
824       	      }
825       	  }
826 }
827 	if( errorFlag)
828 	{
829 		delete dest;
830 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
831 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to ULONG.");
832 	}
833 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
834       	return dest;
835       }
836     case GDL_LONG64:
837       {
838       	Data_<SpDLong64>* dest=new Data_<SpDLong64>( dim, BaseGDL::NOZERO);
839 TRACEOMP( __FILE__, __LINE__)
840 #pragma omp parallel shared( errorFlag, mode)
841 {
842 #pragma omp for
843       	for( OMPInt i=0; i < nEl; ++i)
844       	  {
845       	    const char* cStart=(*this)[i].c_str();
846       	    char* cEnd;
847       	    (*dest)[i]=strtoll(cStart,&cEnd,10);
848       	    if( cEnd == cStart && (*this)[i] != "")
849       	      {
850 StringConversionError( errorFlag, mode, "Type conversion error: "
851 				       "Unable to convert given STRING: '"+
852 				       (*this)[i]+"' to LONG64.");
853       	      }
854       	  }
855 }
856 	if( errorFlag)
857 	{
858 		delete dest;
859 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
860 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to LONG64.");
861 	}
862 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
863       	return dest;
864       }
865     case GDL_ULONG64:
866       {
867       	Data_<SpDULong64>* dest=new Data_<SpDULong64>( dim, BaseGDL::NOZERO);
868 TRACEOMP( __FILE__, __LINE__)
869 #pragma omp parallel shared( errorFlag, mode)
870 {
871 #pragma omp for
872       	for( OMPInt i=0; i < nEl; ++i)
873       	  {
874       	    const char* cStart=(*this)[i].c_str();
875       	    char* cEnd;
876       	    (*dest)[i]=strtoull(cStart,&cEnd,10);
877       	    if( cEnd == cStart && (*this)[i] != "")
878       	      {
879 StringConversionError( errorFlag, mode, "Type conversion error: "
880 				       "Unable to convert given STRING: '"+
881 				       (*this)[i]+"' to ULONG64.");
882       	      }
883       	  }
884 }
885 	if( errorFlag)
886 	{
887 		delete dest;
888 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
889 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to ULONG64.");
890 	}
891 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
892       	return dest;
893       }
894     case GDL_FLOAT:
895       {
896       	Data_<SpDFloat>* dest=new Data_<SpDFloat>( dim, BaseGDL::NOZERO);
897 TRACEOMP( __FILE__, __LINE__)
898 #pragma omp parallel shared( errorFlag, mode)
899 {
900 #pragma omp for
901       	for( OMPInt i=0; i < nEl; ++i)
902       	  {
903       	    const char* cStart=(*this)[i].c_str();
904       	    char* cEnd;
905       	    (*dest)[i] = string2real<float>(cStart, &cEnd);
906       	    if((cEnd == cStart && (*this)[i] != "")) //  || (cEnd - cStart) != strlen(cStart)) // reports error for "16 "
907       	      {
908 StringConversionError( errorFlag, mode, "Type conversion error: "
909 				       "Unable to convert given STRING: '"+
910 				       (*this)[i]+"' to FLOAT.");
911       	      }
912       	  }
913 }
914 	if( errorFlag)
915 	{
916 		delete dest;
917 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
918 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to FLOAT.");
919 	}
920 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
921       	return dest;
922       }
923     case GDL_DOUBLE:
924       {
925       	Data_<SpDDouble>* dest=new Data_<SpDDouble>( dim, BaseGDL::NOZERO);
926 TRACEOMP( __FILE__, __LINE__)
927 #pragma omp parallel shared( errorFlag, mode)
928 {
929 #pragma omp for
930       	for( OMPInt i=0; i < nEl; ++i)
931       	  {
932       	    const char* cStart=(*this)[i].c_str();
933 	    char* cEnd;
934 	    (*dest)[i] = string2real<double>( cStart, &cEnd);
935 	    if( (cEnd == cStart && (*this)[i] != "")) // || (cEnd - cStart) != strlen(cStart)) // reports error for "16 "
936 	      {
937 StringConversionError( errorFlag, mode, "Type conversion error: "
938 				       "Unable to convert given STRING: '"+
939 				       (*this)[i]+"' to DOUBLE.");
940 	      }
941       	  }
942 }
943 	if( errorFlag)
944 	{
945 		delete dest;
946 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
947 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to DOUBLE.");
948 	}
949 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
950       	return dest;
951       }
952       //    case GDL_STRING:
953     case GDL_COMPLEX:
954       {
955       	Data_<SpDComplex>* dest=new Data_<SpDComplex>( dim, BaseGDL::NOZERO);
956 TRACEOMP( __FILE__, __LINE__)
957 #pragma omp parallel shared( errorFlag, mode)
958 {
959 #pragma omp for
960       	for( OMPInt i=0; i < nEl; ++i)
961       	  {
962       	    const char* cStart=(*this)[i].c_str();
963       	    char* cEnd;
964       	    (*dest)[i]=string2real<float>(cStart,&cEnd);
965       	    if((cEnd == cStart && (*this)[i] != "")) // || (cEnd - cStart) != strlen(cStart)) // reports error for "16 "
966       	      {
967 StringConversionError( errorFlag, mode, "Type conversion error: "
968 				       "Unable to convert given STRING: '"+
969 				       (*this)[i]+"' to COMPLEX.");
970       	      }
971       	  }
972 }
973 	if( errorFlag)
974 	{
975 		delete dest;
976 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
977 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to COMPLEX.");
978 	}
979 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
980       	return dest;
981       }
982     case GDL_COMPLEXDBL:
983       {
984       	Data_<SpDComplexDbl>* dest=
985 	  new Data_<SpDComplexDbl>( dim, BaseGDL::NOZERO);
986 TRACEOMP( __FILE__, __LINE__)
987 #pragma omp parallel shared( errorFlag, mode)
988 {
989 #pragma omp for
990       	for( OMPInt i=0; i < nEl; ++i)
991       	  {
992       	    const char* cStart=(*this)[i].c_str();
993       	    char* cEnd;
994       	    (*dest)[i]=string2real<double>(cStart,&cEnd);
995       	    if((cEnd == cStart && (*this)[i] != "")) // || (cEnd - cStart) != strlen(cStart)) // reports error for "16 "
996       	      {
997 StringConversionError( errorFlag, mode, "Type conversion error: "
998 				       "Unable to convert given STRING: '"+
999 				       (*this)[i]+"' to DCOMPLEX.");
1000       	      }
1001       	  }
1002 }
1003 	if( errorFlag)
1004 	{
1005 		delete dest;
1006 		if( (mode & BaseGDL::CONVERT) != 0) delete this;
1007 		throw GDLIOException( "Type conversion error: Unable to convert given STRING to DCOMPLEX.");
1008 	}
1009 	if( (mode & BaseGDL::CONVERT) != 0) delete this;
1010       	return dest;
1011       }
1012     case GDL_PTR:
1013     case GDL_OBJ:
1014     case GDL_STRUCT:
1015     case GDL_UNDEF:
1016     default:
1017 if(BaseGDL::interpreter!=NULL&&BaseGDL::interpreter->CallStack().size()>0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
1018 throw GDLException("Cannot convert to this type.");
1019     }
1020 
1021   // get rid of warning
1022   return NULL;
1023 }
1024 
1025 
1026 
1027 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)1028 template<> BaseGDL* Data_<SpDComplex>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
1029 {
1030 TRACE_CONVERT2
1031   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
1032 
1033   SizeT nEl=dd.size();
1034 
1035   switch( destTy) {
1036     case GDL_BYTE:
1037       DO_CONVERT_START_CPX(SpDByte)
1038 #pragma omp parallel for
1039           DO_CONVERT_END_CPX
1040     case GDL_INT:
1041       DO_CONVERT_START_CPX(SpDInt)
1042 #pragma omp parallel for
1043           DO_CONVERT_END_CPX
1044     case GDL_UINT:
1045       DO_CONVERT_START_CPX(SpDUInt)
1046 #pragma omp parallel for
1047           DO_CONVERT_END_CPX
1048     case GDL_LONG:
1049       DO_CONVERT_START_CPX(SpDLong)
1050 #pragma omp parallel for
1051           DO_CONVERT_END_CPX
1052   case GDL_ULONG:
1053       DO_CONVERT_START_CPX(SpDULong)
1054 #pragma omp parallel for
1055           DO_CONVERT_END_CPX
1056   case GDL_LONG64:
1057       DO_CONVERT_START_CPX(SpDLong64)
1058 #pragma omp parallel for
1059           DO_CONVERT_END_CPX
1060     case GDL_ULONG64:
1061       DO_CONVERT_START_CPX(SpDULong64)
1062 #pragma omp parallel for
1063           DO_CONVERT_END_CPX
1064     case GDL_FLOAT:
1065       DO_CONVERT_START_CPX(SpDFloat)
1066 #pragma omp parallel for
1067           DO_CONVERT_END_CPX
1068     case GDL_DOUBLE:
1069       DO_CONVERT_START_CPX(SpDDouble)
1070 #pragma omp parallel for
1071           DO_CONVERT_END_CPX
1072     case GDL_COMPLEX:    return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
1073     case GDL_COMPLEXDBL:
1074       DO_CONVERT_START(SpDComplexDbl)
1075 #pragma omp parallel for
1076           DO_CONVERT_END
1077     case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
1078     {
1079       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
1080 #pragma omp parallel for
1081 
1082 //FUTURE WORK: the version below is incredibely fast
1083       // using 'code=[1,2,3,4,5,6,7,9,12,13,14,15] & tic & for i=6,6 do begin a=cindgen(10LL^8) & b=fix(a,type=code[i]) & help,b & print,b[-1] & end & toc'
1084       // I get 18 seconds instead of 71 seconds on IDL. However the adaptive formatting of IDL must be respected, so this has to be completed. Probably in io.cpp
1085 //      for (SizeT i = 0; i < nEl; ++i) {
1086 //        (*dest)[i].resize(32);
1087 //        snprintf(&((*dest)[i])[0],32,"(%13g,%13g)",(*this)[i].real(),(*this)[i].imag());
1088 //      }
1089    for( SizeT i=0; i < nEl; ++i)  (*dest)[i]="("+i2s(real((*this)[i]))+","+i2s(imag((*this)[i]))+")";
1090       if ((mode & BaseGDL::CONVERT) != 0) delete this;
1091       return dest;
1092     }
1093     case GDL_PTR:
1094     case GDL_OBJ:
1095     case GDL_STRUCT:
1096     case GDL_UNDEF:
1097     default:
1098       if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
1099       throw GDLException("Cannot convert to this type.");
1100     }
1101 
1102   return NULL; // get rid of warning
1103 }
1104 
1105 
1106 
1107 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)1108 template<> BaseGDL* Data_<SpDComplexDbl>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
1109 {
1110 TRACE_CONVERT2
1111   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
1112 
1113   SizeT nEl=dd.size();
1114 
1115   switch( destTy) {
1116     case GDL_BYTE:
1117       DO_CONVERT_START_CPX(SpDByte)
1118 #pragma omp parallel for
1119           DO_CONVERT_END_CPX
1120     case GDL_INT:
1121       DO_CONVERT_START_CPX(SpDInt)
1122 #pragma omp parallel for
1123           DO_CONVERT_END_CPX
1124     case GDL_UINT:
1125       DO_CONVERT_START_CPX(SpDUInt)
1126 #pragma omp parallel for
1127           DO_CONVERT_END_CPX
1128     case GDL_LONG:
1129       DO_CONVERT_START_CPX(SpDLong)
1130 #pragma omp parallel for
1131           DO_CONVERT_END_CPX
1132   case GDL_ULONG:
1133       DO_CONVERT_START_CPX(SpDULong)
1134 #pragma omp parallel for
1135           DO_CONVERT_END_CPX
1136   case GDL_LONG64:
1137       DO_CONVERT_START_CPX(SpDLong64)
1138 #pragma omp parallel for
1139           DO_CONVERT_END_CPX
1140     case GDL_ULONG64:
1141       DO_CONVERT_START_CPX(SpDULong64)
1142 #pragma omp parallel for
1143           DO_CONVERT_END_CPX
1144     case GDL_FLOAT:
1145       DO_CONVERT_START_CPX(SpDFloat)
1146 #pragma omp parallel for
1147           DO_CONVERT_END_CPX
1148     case GDL_DOUBLE:
1149       DO_CONVERT_START_CPX(SpDDouble)
1150 #pragma omp parallel for
1151           DO_CONVERT_END_CPX
1152     case GDL_COMPLEX:
1153       DO_CONVERT_START(SpDComplex)
1154 #pragma omp parallel for
1155           DO_CONVERT_END
1156     case GDL_COMPLEXDBL:   return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
1157     case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
1158     {
1159       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
1160 #pragma omp parallel for
1161       for (SizeT i = 0; i < nEl; ++i) (*dest)[i]="("+i2s(real((*this)[i]))+","+i2s(imag((*this)[i]))+")";
1162       if ((mode & BaseGDL::CONVERT) != 0) delete this;
1163       return dest;
1164     }
1165     case GDL_PTR:
1166     case GDL_OBJ:
1167     case GDL_STRUCT:
1168     case GDL_UNDEF:
1169     default:
1170       if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
1171       throw GDLException("Cannot convert to this type.");
1172     }
1173 
1174   return NULL; // get rid of warning
1175 }
1176 
1177 
1178 
1179 
1180 // 64 bit integers
Convert2(DType destTy,BaseGDL::Convert2Mode mode)1181 template<> BaseGDL* Data_<SpDLong64>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
1182 {
1183 TRACE_CONVERT2
1184   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
1185 
1186   SizeT nEl=dd.size();
1187 
1188 
1189     switch (destTy) {
1190     case GDL_BYTE:
1191       DO_CONVERT_START(SpDByte)
1192 #pragma omp parallel for
1193           DO_CONVERT_END
1194     case GDL_INT:
1195       DO_CONVERT_START(SpDInt)
1196 #pragma omp parallel for
1197           DO_CONVERT_END
1198     case GDL_UINT:
1199       DO_CONVERT_START(SpDUInt)
1200 #pragma omp parallel for
1201           DO_CONVERT_END
1202     case GDL_LONG:
1203       DO_CONVERT_START(SpDLong)
1204 #pragma omp parallel for
1205           DO_CONVERT_END
1206     case GDL_ULONG:
1207       DO_CONVERT_START(SpDULong)
1208 #pragma omp parallel for
1209           DO_CONVERT_END
1210     case GDL_LONG64:       return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
1211     case GDL_ULONG64:
1212       DO_CONVERT_START(SpDULong64)
1213 #pragma omp parallel for
1214           DO_CONVERT_END
1215     case GDL_FLOAT:
1216       DO_CONVERT_START(SpDFloat)
1217 #pragma omp parallel for
1218           DO_CONVERT_END
1219     case GDL_DOUBLE:
1220       DO_CONVERT_START(SpDDouble)
1221 #pragma omp parallel for
1222           DO_CONVERT_END
1223     case GDL_COMPLEX:
1224       DO_CONVERT_START(SpDComplex)
1225 #pragma omp parallel for
1226           DO_CONVERT_END
1227     case GDL_COMPLEXDBL:
1228       DO_CONVERT_START(SpDComplexDbl)
1229 #pragma omp parallel for
1230           DO_CONVERT_END
1231     case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
1232     {
1233       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
1234 #pragma omp parallel for
1235       for (SizeT i = 0; i < nEl; ++i) (*dest)[i] = i2s((*this)[i], 22);
1236       if ((mode & BaseGDL::CONVERT) != 0) delete this;
1237       return dest;
1238     }
1239     case GDL_PTR:
1240     case GDL_OBJ:
1241     case GDL_STRUCT:
1242     case GDL_UNDEF:
1243     default:
1244       if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
1245       throw GDLException("Cannot convert to this type.");
1246     }
1247 
1248    // get rid of warning
1249   return NULL;
1250 }
1251 
1252 
1253 
Convert2(DType destTy,BaseGDL::Convert2Mode mode)1254 template<> BaseGDL* Data_<SpDULong64>::Convert2( DType destTy, BaseGDL::Convert2Mode mode)
1255 {
1256 TRACE_CONVERT2
1257   if( destTy == t) return (((mode & BaseGDL::COPY) != 0)?Dup():this);
1258 
1259   SizeT nEl=dd.size();
1260 
1261 
1262     switch (destTy) {
1263     case GDL_BYTE:
1264       DO_CONVERT_START(SpDByte)
1265 #pragma omp parallel for
1266           DO_CONVERT_END
1267     case GDL_INT:
1268       DO_CONVERT_START(SpDInt)
1269 #pragma omp parallel for
1270           DO_CONVERT_END
1271     case GDL_UINT:
1272       DO_CONVERT_START(SpDUInt)
1273 #pragma omp parallel for
1274           DO_CONVERT_END
1275     case GDL_LONG:
1276       DO_CONVERT_START(SpDLong)
1277 #pragma omp parallel for
1278           DO_CONVERT_END
1279     case GDL_ULONG:
1280       DO_CONVERT_START(SpDULong)
1281 #pragma omp parallel for
1282           DO_CONVERT_END
1283     case GDL_LONG64:
1284       DO_CONVERT_START(SpDLong64)
1285 #pragma omp parallel for
1286           DO_CONVERT_END
1287     case GDL_ULONG64:       return (((mode & BaseGDL::COPY) != 0) ? Dup():this);
1288     case GDL_FLOAT:
1289       DO_CONVERT_START(SpDFloat)
1290 #pragma omp parallel for
1291           DO_CONVERT_END
1292     case GDL_DOUBLE:
1293       DO_CONVERT_START(SpDDouble)
1294 #pragma omp parallel for
1295           DO_CONVERT_END
1296     case GDL_COMPLEX:
1297       DO_CONVERT_START(SpDComplex)
1298 #pragma omp parallel for
1299           DO_CONVERT_END
1300     case GDL_COMPLEXDBL:
1301       DO_CONVERT_START(SpDComplexDbl)
1302 #pragma omp parallel for
1303           DO_CONVERT_END
1304     case GDL_STRING: // GDL_BYTE to GDL_STRING: remove first dim
1305     {
1306       Data_<SpDString>* dest = new Data_<SpDString>(dim, BaseGDL::NOZERO);
1307 #pragma omp parallel for
1308       for (SizeT i = 0; i < nEl; ++i) (*dest)[i] = i2s((*this)[i], 22);
1309       if ((mode & BaseGDL::CONVERT) != 0) delete this;
1310       return dest;
1311     }
1312     case GDL_PTR:
1313     case GDL_OBJ:
1314     case GDL_STRUCT:
1315     case GDL_UNDEF:
1316     default:
1317       if (BaseGDL::interpreter != NULL && BaseGDL::interpreter->CallStack().size() > 0) BaseGDL::interpreter->CallStack().back()->Throw("Cannot convert to this type.");
1318       throw GDLException("Cannot convert to this type.");
1319     }
1320 
1321    // get rid of warning
1322   return NULL;
1323 }
1324