1 /**************************************************************************
2 datatypesref.cpp - specializations for DPtrGDL and DObjGDL for reference counting
3 -------------------
4 begin : March 08 2010
5 copyright : (C) 2010 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 // to be included from datatypes.cpp
19 #ifdef INCLUDE_DATATYPESREF_CPP
20 #undef INCLUDE_DATATYPESREF_CPP
21 #include "nullgdl.hpp"
22
23 // reference counting for INIT
24 template<>
New(const dimension & dim_,BaseGDL::InitType noZero) const25 Data_<SpDPtr>* Data_<SpDPtr>::New( const dimension& dim_, BaseGDL::InitType noZero) const
26 {
27 if( noZero == BaseGDL::NOZERO) return new Data_(dim_, BaseGDL::NOZERO);
28 if( noZero == BaseGDL::INIT)
29 {
30 Data_* res = new Data_(dim_, BaseGDL::NOZERO);
31 SizeT nEl = res->dd.size();
32 /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl))
33 {
34 #pragma omp for*/
35 for( OMPInt i=0; i<nEl; ++i) (*res)[ i] = (*this)[ 0]; // set all to scalar
36 //}
37 GDLInterpreter::AddRef((*this)[ 0], nEl);
38
39 return res;
40 }
41 return new Data_(dim_); // zero data
42 }
43 // reference counting for INIT
44 template<>
New(const dimension & dim_,BaseGDL::InitType noZero) const45 Data_<SpDObj>* Data_<SpDObj>::New( const dimension& dim_, BaseGDL::InitType noZero) const
46 {
47 if( noZero == BaseGDL::NOZERO) return new Data_(dim_, BaseGDL::NOZERO);
48 if( noZero == BaseGDL::INIT)
49 {
50 Data_* res = new Data_(dim_, BaseGDL::NOZERO);
51 SizeT nEl = res->dd.size();
52 /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl))
53 {
54 #pragma omp for*/
55 for( OMPInt i=0; i<nEl; ++i) (*res)[ i] = (*this)[ 0]; // set all to scalar
56 //}
57 GDLInterpreter::AddRefObj((*this)[ 0], nEl);
58
59 return res;
60 }
61 return new Data_(dim_); // zero data
62 }
63
64 template<>
InsAt(Data_ * srcIn,ArrayIndexListT * ixList,SizeT offset)65 void Data_<SpDPtr>::InsAt( Data_* srcIn, ArrayIndexListT* ixList, SizeT offset)
66 {
67 // max. number of dimensions to copy
68 SizeT nDim = ixList->NDim();
69
70 if( nDim == 1)
71 {
72 SizeT destStart = ixList->LongIx();
73
74 //SizeT len;
75 if( this->N_Elements() == 1)
76 {
77 // len = 1;
78 SizeT rStride = srcIn->Stride(this->Rank());
79 Ty& a = (*this)[ destStart];
80 Ty b = (*srcIn)[ offset/rStride];
81 GDLInterpreter::IncRef( b);
82 GDLInterpreter::DecRef( a);
83 a = b;//(*this)[ destStart] = (*srcIn)[ offset/rStride];
84 }
85 else
86 {
87 SizeT len = srcIn->Dim( 0); // length of segment to copy
88 // TODO: IDL reports here (and probably in the insert-dimension case below as well)
89 // the name of a variable, e.g.:
90 // IDL> a=[0,0,0] & a[2]=[2,2,2]
91 // % Out of range subscript encountered: A.
92 if( (destStart+len) > this->N_Elements()) //dim[0])
93 throw GDLException("Out of range subscript encountered (length of insert exceeds array boundaries).");
94
95 // DataT& srcIn_dd = srcIn->dd;
96 SizeT srcIx = 0; // this one simply runs from 0 to N_Elements(srcIn)
97
98 SizeT destEnd = destStart + len;
99 for( SizeT destIx = destStart; destIx < destEnd; ++destIx)
100 {
101 Ty& a = (*this)[ destIx];
102 Ty b = (*srcIn)[ srcIx++];
103 GDLInterpreter::IncRef( b);
104 GDLInterpreter::DecRef( a);
105
106 a = b;// (*this)[ destIx] = (*srcIn)[ srcIx++];
107 }
108 }
109
110 return;
111 }
112
113 SizeT destStart; // 1-dim starting index
114 // ATTENTION: dimension is used as an index here
115 dimension ixDim = ixList->GetDimIx0( destStart);
116 nDim--;
117
118 dimension srcDim=srcIn->Dim();
119 srcDim.Purge(); // newly inserted: variant of ticket #675
120 SizeT len=srcDim[0]; // length of one segment to copy (one line of srcIn)
121
122 // SizeT nDim =RankIx(ixDim.Rank());
123 SizeT srcNDim=RankIx(srcDim.Rank()); // number of source dimensions
124 if( srcNDim < nDim) nDim=srcNDim;
125
126 // check limits (up to Rank to consider)
127 for( SizeT dIx=0; dIx <= nDim; ++dIx)
128 // check if in bounds of a
129 if( (ixDim[dIx]+srcDim[dIx]) > this->dim[dIx])
130 throw GDLException("Out of range subscript encountered (dimension of insert exceeds array boundaries for dimension " + i2s(dIx +1) + ").");
131
132 SizeT nCp=srcIn->Stride(nDim+1)/len; // number of OVERALL copy actions
133
134 // as lines are copied, we need the stride from 2nd dim on
135 SizeT retStride[MAXRANK+1];
136 for( SizeT a=0; a <= nDim; ++a) retStride[a]=srcDim.Stride(a+1)/len;
137
138 // a magic number, to reset destStart for this dimension
139 SizeT resetStep[MAXRANK+1];
140 for( SizeT a=1; a <= nDim; ++a)
141 resetStep[a]=(retStride[a]-1)/retStride[a-1]*this->dim.Stride(a);
142
143 // SizeT destStart=this->dim.LongIndex(ixDim); // starting pos
144
145 // DataT& srcIn_dd = srcIn->dd;
146
147 SizeT srcIx=0; // this one simply runs from 0 to N_Elements(srcIn)
148 for( SizeT c=1; c<=nCp; ++c) // linearized verison of nested loops
149 {
150 // copy one segment
151 SizeT destEnd=destStart+len;
152 for( SizeT destIx=destStart; destIx<destEnd; ++destIx)
153 {
154 Ty& a = (*this)[ destIx];
155 Ty b = (*srcIn)[ srcIx++];
156 GDLInterpreter::IncRef( b);
157 GDLInterpreter::DecRef( a);
158 a = b;//(*this)[destIx] = (*srcIn)[ srcIx++];
159 }
160
161 // update destStart for all dimensions
162 if( c < nCp)
163 for( SizeT a=1; a<=nDim; ++a)
164 {
165 if( c % retStride[a])
166 {
167 // advance to next
168 destStart += this->dim.Stride(a);
169 break;
170 }
171 else
172 {
173 // reset
174 destStart -= resetStep[a];
175 }
176 }
177 }
178 }
179
180 template<>
InsAt(Data_ * srcIn,ArrayIndexListT * ixList,SizeT offset)181 void Data_<SpDObj>::InsAt( Data_* srcIn, ArrayIndexListT* ixList, SizeT offset)
182 {
183 // max. number of dimensions to copy
184 SizeT nDim = ixList->NDim();
185
186 if( nDim == 1)
187 {
188 SizeT destStart = ixList->LongIx();
189
190 //SizeT len;
191 if( this->N_Elements() == 1)
192 {
193 // len = 1;
194 SizeT rStride = srcIn->Stride(this->Rank());
195 Ty& a = (*this)[ destStart];
196 Ty b = (*srcIn)[ offset/rStride];
197 GDLInterpreter::IncRefObj( b);
198 GDLInterpreter::DecRefObj( a);
199 a = b;//(*this)[ destStart] = (*srcIn)[ offset/rStride];
200 }
201 else
202 {
203 SizeT len = srcIn->Dim( 0); // length of segment to copy
204 // TODO: IDL reports here (and probably in the insert-dimension case below as well)
205 // the name of a variable, e.g.:
206 // IDL> a=[0,0,0] & a[2]=[2,2,2]
207 // % Out of range subscript encountered: A.
208 if( (destStart+len) > this->N_Elements()) //dim[0])
209 throw GDLException("Out of range subscript encountered (length of insert exceeds array boundaries).");
210
211 // DataT& srcIn_dd = srcIn->dd;
212 SizeT srcIx = 0; // this one simply runs from 0 to N_Elements(srcIn)
213
214 SizeT destEnd = destStart + len;
215 for( SizeT destIx = destStart; destIx < destEnd; ++destIx)
216 {
217 Ty& a = (*this)[ destIx];
218 Ty b = (*srcIn)[ srcIx++];
219 GDLInterpreter::IncRefObj( b);
220 GDLInterpreter::DecRefObj( a);
221
222 a = b;// (*this)[ destIx] = (*srcIn)[ srcIx++];
223 }
224 }
225
226 return;
227 }
228
229 SizeT destStart; // 1-dim starting index
230 // ATTENTION: dimension is used as an index here
231 dimension ixDim = ixList->GetDimIx0( destStart);
232 nDim--;
233
234 dimension srcDim=srcIn->Dim();
235 srcDim.Purge(); // newly inserted: variant of ticket #675
236 SizeT len=srcDim[0]; // length of one segment to copy (one line of srcIn)
237
238 // SizeT nDim =RankIx(ixDim.Rank());
239 SizeT srcNDim=RankIx(srcDim.Rank()); // number of source dimensions
240 if( srcNDim < nDim) nDim=srcNDim;
241
242 // check limits (up to Rank to consider)
243 for( SizeT dIx=0; dIx <= nDim; ++dIx)
244 // check if in bounds of a
245 if( (ixDim[dIx]+srcDim[dIx]) > this->dim[dIx])
246 throw GDLException("Out of range subscript encountered (dimension of insert exceeds array boundaries for dimension " + i2s(dIx +1) + ").");
247
248 SizeT nCp=srcIn->Stride(nDim+1)/len; // number of OVERALL copy actions
249
250 // as lines are copied, we need the stride from 2nd dim on
251 SizeT retStride[MAXRANK];
252 for( SizeT a=0; a <= nDim; ++a) retStride[a]=srcDim.Stride(a+1)/len;
253
254 // a magic number, to reset destStart for this dimension
255 SizeT resetStep[MAXRANK];
256 for( SizeT a=1; a <= nDim; ++a)
257 resetStep[a]=(retStride[a]-1)/retStride[a-1]*this->dim.Stride(a);
258
259 // SizeT destStart=this->dim.LongIndex(ixDim); // starting pos
260
261 // DataT& srcIn_dd = srcIn->dd;
262
263 SizeT srcIx=0; // this one simply runs from 0 to N_Elements(srcIn)
264 for( SizeT c=1; c<=nCp; ++c) // linearized verison of nested loops
265 {
266 // copy one segment
267 SizeT destEnd=destStart+len;
268 for( SizeT destIx=destStart; destIx<destEnd; ++destIx)
269 {
270 Ty& a = (*this)[ destIx];
271 Ty b = (*srcIn)[ srcIx++];
272 GDLInterpreter::IncRefObj( b);
273 GDLInterpreter::DecRefObj( a);
274 a = b;//(*this)[destIx] = (*srcIn)[ srcIx++];
275 }
276
277 // update destStart for all dimensions
278 if( c < nCp)
279 for( SizeT a=1; a<=nDim; ++a)
280 {
281 if( c % retStride[a])
282 {
283 // advance to next
284 destStart += this->dim.Stride(a);
285 break;
286 }
287 else
288 {
289 // reset
290 destStart -= resetStep[a];
291 }
292 }
293 }
294 }
295
296
297
298 template<>
AssignAtIx(RangeT ix,BaseGDL * srcIn)299 void Data_<SpDPtr>::AssignAtIx( RangeT ix, BaseGDL* srcIn)
300 {
301 if( srcIn->Type() != this->Type())
302 throw GDLException("Only expressions of type " + srcIn->TypeStr() + " can be assigned to " + this->TypeStr());
303 GDLInterpreter::IncRef( (*static_cast<Data_*>(srcIn))[0]);
304 GDLInterpreter::DecRef( (*this)[ix]);
305 (*this)[ix] = (*static_cast<Data_*>(srcIn))[0];
306 }
307 template<>
AssignAtIx(RangeT ix,BaseGDL * srcIn)308 void Data_<SpDObj>::AssignAtIx( RangeT ix, BaseGDL* srcIn)
309 {
310 if( srcIn->Type() != this->Type())
311 throw GDLException("Only expressions of type " + srcIn->TypeStr() + " can be assigned to " + this->TypeStr());
312 GDLInterpreter::IncRefObj( (*static_cast<Data_*>(srcIn))[0]);
313 GDLInterpreter::DecRefObj( (*this)[ix]);
314 (*this)[ix] = (*static_cast<Data_*>(srcIn))[0];
315 }
316
317
318
319
320
321
322
323
324
325
326 template<>
AssignAt(BaseGDL * srcIn,ArrayIndexListT * ixList,SizeT offset)327 void Data_<SpDPtr>::AssignAt( BaseGDL* srcIn, ArrayIndexListT* ixList, SizeT offset)
328 {
329 // breakpoint(); // gdbg can not handle breakpoints in template functions
330 Data_* src = static_cast<Data_*>(srcIn);
331
332 SizeT srcElem= src->N_Elements();
333 // bool isScalar= (srcElem == 1);
334 bool isScalar= (srcElem == 1) && (src->Rank() == 0);
335 if( isScalar)
336 { // src is scalar
337 Ty scalar=(*src)[0];
338
339 if( ixList == NULL)
340 {
341 SizeT nCp=Data_::N_Elements();
342
343 GDLInterpreter::AddRef( scalar, nCp);
344
345 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
346 {
347 //#pragma omp for
348 for( SizeT c=0; c<nCp; ++c)
349 {
350 GDLInterpreter::DecRef( (*this)[ c]);
351 (*this)[ c]=scalar;
352 }
353 }
354 }
355 else
356 {
357 SizeT nCp=ixList->N_Elements();
358
359 AllIxBaseT* allIx = ixList->BuildIx();
360
361 GDLInterpreter::AddRef( scalar, nCp);
362
363 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
364 {
365 //#pragma omp for
366 for( SizeT c=0; c<nCp; ++c)
367 {
368 SizeT ix = (*allIx)[ c];
369 GDLInterpreter::DecRef( (*this)[ ix]);
370 (*this)[ ix]=scalar;
371 }
372 } // (*this)[ ixList->GetIx( c)]=scalar;
373 }
374 }
375 else
376 {
377 if( ixList == NULL)
378 {
379 SizeT nCp=Data_::N_Elements();
380
381 // if (non-indexed) src is smaller -> just copy its number of elements
382 if( nCp > (srcElem-offset)) {
383 if( offset == 0)
384 nCp=srcElem;
385 else
386 throw GDLException("Source expression contains not enough elements.");
387 }
388 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
389 {
390 //#pragma omp for
391 for( SizeT c=0; c<nCp; ++c)
392 {
393 Ty& a = (*this)[ c];
394 Ty b = (*src)[c+offset];
395 GDLInterpreter::IncRef( b);
396 GDLInterpreter::DecRef( a);
397 a = b;//(*this)[ c]=(*src)[c+offset];
398 }
399 }
400 }
401 else
402 {
403 // crucial part
404 SizeT nCp=ixList->N_Elements();
405
406 if( nCp == 1)
407 {
408 SizeT destStart = ixList->LongIx();
409 // len = 1;
410 SizeT rStride = srcIn->Stride(this->Rank());
411 (*this)[ destStart] = (*src)[ offset/rStride];
412
413 // InsAt( src, ixList, offset);
414 }
415 else
416 {
417 if( offset == 0)
418 {
419 if( srcElem < nCp)
420 throw GDLException("Array subscript must have same size as"
421 " source expression.");
422
423 AllIxBaseT* allIx = ixList->BuildIx();
424 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
425 {
426 //#pragma omp for
427 for( SizeT c=0; c<nCp; ++c)
428 {
429 Ty& a = (*this)[ (*allIx)[ c]];
430 Ty b = (*src)[c];
431 GDLInterpreter::IncRef( b);
432 GDLInterpreter::DecRef( a);
433 a = b;// (*this)[ (*allIx)[ c]]=(*src)[c];
434 }
435 } // (*this)[ ixList->GetIx( c)]=(*src)[c+offset];
436 }
437 else
438 {
439 if( (srcElem-offset) < nCp)
440 throw GDLException("Array subscript must have same size as"
441 " source expression.");
442
443 AllIxBaseT* allIx = ixList->BuildIx();
444 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
445 {
446 //#pragma omp for
447 for( SizeT c=0; c<nCp; ++c)
448 {
449 Ty& a = (*this)[ (*allIx)[ c]];
450 Ty b = (*src)[c+offset];
451 GDLInterpreter::IncRef( b);
452 GDLInterpreter::DecRef( a);
453 a = b;// (*this)[ (*allIx)[ c]]=(*src)[c+offset];
454 }
455 } // (*this)[ ixList->GetIx( c)]=(*src)[c+offset];
456 }
457 }
458 }
459 }
460 }
461
462 template<>
AssignAt(BaseGDL * srcIn,ArrayIndexListT * ixList,SizeT offset)463 void Data_<SpDObj>::AssignAt( BaseGDL* srcIn, ArrayIndexListT* ixList, SizeT offset)
464 {
465 // breakpoint(); // gdbg can not handle breakpoints in template functions
466 Data_* src = static_cast<Data_*>(srcIn);
467
468 SizeT srcElem= src->N_Elements();
469 // bool isScalar= (srcElem == 1);
470 bool isScalar= (srcElem == 1) && (src->Rank() == 0);
471 if( isScalar)
472 { // src is scalar
473 Ty scalar=(*src)[0];
474
475 if( ixList == NULL)
476 {
477 SizeT nCp=Data_::N_Elements();
478
479 GDLInterpreter::AddRefObj( scalar, nCp);
480
481 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
482 {
483 //#pragma omp for
484 for( SizeT c=0; c<nCp; ++c)
485 {
486 GDLInterpreter::DecRefObj( (*this)[ c]);
487 (*this)[ c]=scalar;
488 }
489 }
490 }
491 else
492 {
493 SizeT nCp=ixList->N_Elements();
494
495 AllIxBaseT* allIx = ixList->BuildIx();
496
497 GDLInterpreter::AddRefObj( scalar, nCp);
498
499 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
500 {
501 //#pragma omp for
502 for( SizeT c=0; c<nCp; ++c)
503 {
504 SizeT ix = (*allIx)[ c];
505 GDLInterpreter::DecRefObj( (*this)[ ix]);
506 (*this)[ ix]=scalar;
507 }
508 } // (*this)[ ixList->GetIx( c)]=scalar;
509 }
510 }
511 else
512 {
513 if( ixList == NULL)
514 {
515 SizeT nCp=Data_::N_Elements();
516
517 // if (non-indexed) src is smaller -> just copy its number of elements
518 if( nCp > (srcElem-offset)) {
519 if( offset == 0)
520 nCp=srcElem;
521 else
522 throw GDLException("Source expression contains not enough elements.");
523 }
524 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
525 {
526 //#pragma omp for
527 for( SizeT c=0; c<nCp; ++c)
528 {
529 Ty& a = (*this)[ c];
530 Ty b = (*src)[c+offset];
531 GDLInterpreter::IncRefObj( b);
532 GDLInterpreter::DecRefObj( a);
533 a = b;//(*this)[ c]=(*src)[c+offset];
534 }
535 }
536 }
537 else
538 {
539 // crucial part
540 SizeT nCp=ixList->N_Elements();
541
542 if( nCp == 1)
543 {
544 SizeT destStart = ixList->LongIx();
545 // len = 1;
546 SizeT rStride = srcIn->Stride(this->Rank());
547 (*this)[ destStart] = (*src)[ offset/rStride];
548
549 // InsAt( src, ixList, offset);
550 }
551 else
552 {
553 if( offset == 0)
554 {
555 if( srcElem < nCp)
556 throw GDLException("Array subscript must have same size as"
557 " source expression.");
558
559 AllIxBaseT* allIx = ixList->BuildIx();
560 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
561 {
562 //#pragma omp for
563 for( SizeT c=0; c<nCp; ++c)
564 {
565 Ty& a = (*this)[ (*allIx)[ c]];
566 Ty b = (*src)[c];
567 GDLInterpreter::IncRefObj( b);
568 GDLInterpreter::DecRefObj( a);
569 a = b;// (*this)[ (*allIx)[ c]]=(*src)[c];
570 }
571 } // (*this)[ ixList->GetIx( c)]=(*src)[c+offset];
572 }
573 else
574 {
575 if( (srcElem-offset) < nCp)
576 throw GDLException("Array subscript must have same size as"
577 " source expression.");
578
579 AllIxBaseT* allIx = ixList->BuildIx();
580 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
581 {
582 //#pragma omp for
583 for( SizeT c=0; c<nCp; ++c)
584 {
585 Ty& a = (*this)[ (*allIx)[ c]];
586 Ty b = (*src)[c+offset];
587 GDLInterpreter::IncRefObj( b);
588 GDLInterpreter::DecRefObj( a);
589 a = b;// (*this)[ (*allIx)[ c]]=(*src)[c+offset];
590 }
591 } // (*this)[ ixList->GetIx( c)]=(*src)[c+offset];
592 }
593 }
594 }
595 }
596 }
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630 template<>
AssignAt(BaseGDL * srcIn,ArrayIndexListT * ixList)631 void Data_<SpDPtr>::AssignAt( BaseGDL* srcIn, ArrayIndexListT* ixList)
632 {
633 assert( ixList != NULL);
634
635 // breakpoint(); // gdbg can not handle breakpoints in template functions
636 Data_* src = static_cast<Data_*>(srcIn);
637
638 SizeT srcElem= src->N_Elements();
639 bool isScalar= (srcElem == 1);
640 if( isScalar)
641 { // src is scalar
642 SizeT nCp=ixList->N_Elements();
643
644 if( nCp == 1)
645 {
646 Ty& a = (*this)[ ixList->LongIx()] ;
647 Ty b = (*src)[ 0];
648 GDLInterpreter::IncRef( b);
649 GDLInterpreter::DecRef( a);
650 a = b;//(*this)[ ixList->LongIx()] = (*src)[0];
651 }
652 else
653 {
654 Ty scalar=(*src)[0];
655 AllIxBaseT* allIx = ixList->BuildIx();
656
657 GDLInterpreter::AddRef( scalar, nCp);
658
659 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
660 {
661 //#pragma omp for
662 for( SizeT c=0; c<nCp; ++c)
663 {
664 Ty& a = (*this)[ (*allIx)[ c]];
665 // Ty b = scalar;
666 GDLInterpreter::DecRef( a);
667 a = scalar;// (*this)[ (*allIx)[ c]]=scalar;
668 }
669 } // (*this)[ ixList->GetIx( c)]=scalar;
670 }
671 }
672 else
673 {
674 // crucial part
675 SizeT nCp=ixList->N_Elements();
676
677 if( nCp == 1)
678 {
679 InsAt( src, ixList);
680 }
681 else
682 {
683 if( srcElem < nCp)
684 throw GDLException("Array subscript must have same size as"
685 " source expression.");
686
687 AllIxBaseT* allIx = ixList->BuildIx();
688 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
689 {
690 //#pragma omp for
691 for( SizeT c=0; c<nCp; ++c)
692 {
693 Ty& a = (*this)[ (*allIx)[ c]];
694 Ty b = (*src)[c];
695 GDLInterpreter::IncRef( b);
696 GDLInterpreter::DecRef( a);
697 a = b;// (*this)[ (*allIx)[ c]]=(*src)[c];
698 }
699 } // (*this)[ ixList->GetIx( c)]=(*src)[c+offset];
700 }
701 }
702 }
703 template<>
AssignAt(BaseGDL * srcIn)704 void Data_<SpDPtr>::AssignAt( BaseGDL* srcIn)
705 {
706 // breakpoint(); // gdbg can not handle breakpoints in template functions
707 Data_* src = static_cast<Data_*>(srcIn);
708
709 SizeT srcElem= src->N_Elements();
710 bool isScalar= (srcElem == 1);
711 if( isScalar)
712 { // src is scalar
713 Ty scalar=(*src)[0];
714
715 /* dd = scalar;*/
716 SizeT nCp=Data_::N_Elements();
717
718 GDLInterpreter::AddRef( scalar, nCp);
719 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
720 {
721 //#pragma omp for
722 for( SizeT c=0; c<nCp; ++c)
723 {
724 Ty& a = (*this)[ c];
725 GDLInterpreter::DecRef( a);
726 // GDLInterpreter::IncRef( b);
727 a = scalar;//(*this)[ c]=scalar;
728 }
729 }
730 // SizeT nCp=Data_::N_Elements();
731
732 // for( SizeT c=0; c<nCp; ++c)
733 // (*this)[ c]=scalar;
734 }
735 else
736 {
737 SizeT nCp=Data_::N_Elements();
738
739 // if (non-indexed) src is smaller -> just copy its number of elements
740 if( nCp > srcElem) nCp=srcElem;
741
742 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
743 {
744 //#pragma omp for
745 for( SizeT c=0; c<nCp; ++c)
746 {
747 Ty& a = (*this)[ c];
748 Ty b = (*src)[c];
749 GDLInterpreter::IncRef( b);
750 GDLInterpreter::DecRef( a);
751 a = b;//(*this)[ c]=(*src)[c];
752 }
753 }
754 }
755 }
756
757
758 template<>
AssignAt(BaseGDL * srcIn,ArrayIndexListT * ixList)759 void Data_<SpDObj>::AssignAt( BaseGDL* srcIn, ArrayIndexListT* ixList)
760 {
761 assert( ixList != NULL);
762
763 // breakpoint(); // gdbg can not handle breakpoints in template functions
764 Data_* src = static_cast<Data_*>(srcIn);
765
766 SizeT srcElem= src->N_Elements();
767 bool isScalar= (srcElem == 1);
768 if( isScalar)
769 { // src is scalar
770 SizeT nCp=ixList->N_Elements();
771
772 if( nCp == 1)
773 {
774 Ty& a = (*this)[ ixList->LongIx()] ;
775 Ty b = (*src)[ 0];
776 GDLInterpreter::IncRefObj( b);
777 GDLInterpreter::DecRefObj( a);
778 a = b;//(*this)[ ixList->LongIx()] = (*src)[0];
779 }
780 else
781 {
782 Ty scalar=(*src)[0];
783 AllIxBaseT* allIx = ixList->BuildIx();
784
785 GDLInterpreter::AddRefObj( scalar, nCp);
786
787 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
788 {
789 //#pragma omp for
790 for( SizeT c=0; c<nCp; ++c)
791 {
792 Ty& a = (*this)[ (*allIx)[ c]];
793 GDLInterpreter::DecRefObj( a);
794 a = scalar;// (*this)[ (*allIx)[ c]]=scalar;
795 }
796 } // (*this)[ ixList->GetIx( c)]=scalar;
797 }
798 }
799 else
800 {
801 // crucial part
802 SizeT nCp=ixList->N_Elements();
803
804 if( nCp == 1)
805 {
806 InsAt( src, ixList);
807 }
808 else
809 {
810 if( srcElem < nCp)
811 throw GDLException("Array subscript must have same size as"
812 " source expression.");
813
814 AllIxBaseT* allIx = ixList->BuildIx();
815 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
816 {
817 //#pragma omp for
818 for( SizeT c=0; c<nCp; ++c)
819 {
820 Ty& a = (*this)[ (*allIx)[ c]];
821 Ty b = (*src)[c];
822 GDLInterpreter::IncRefObj( b);
823 GDLInterpreter::DecRefObj( a);
824 a = b;// (*this)[ (*allIx)[ c]]=(*src)[c];
825 }
826 } // (*this)[ ixList->GetIx( c)]=(*src)[c+offset];
827 }
828 }
829 }
830 template<>
AssignAt(BaseGDL * srcIn)831 void Data_<SpDObj>::AssignAt( BaseGDL* srcIn)
832 {
833 // breakpoint(); // gdbg can not handle breakpoints in template functions
834 Data_* src = static_cast<Data_*>(srcIn);
835
836 SizeT srcElem= src->N_Elements();
837 bool isScalar= (srcElem == 1);
838 if( isScalar)
839 { // src is scalar
840 Ty scalar=(*src)[0];
841
842 /* dd = scalar;*/
843 SizeT nCp=Data_::N_Elements();
844
845 GDLInterpreter::AddRefObj( scalar, nCp);
846
847 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
848 {
849 //#pragma omp for
850 for( SizeT c=0; c<nCp; ++c)
851 {
852 Ty& a = (*this)[ c];
853 GDLInterpreter::DecRefObj( a);
854 a = scalar;//(*this)[ c]=scalar;
855 }
856 }
857
858 // SizeT nCp=Data_::N_Elements();
859
860 // for( SizeT c=0; c<nCp; ++c)
861 // (*this)[ c]=scalar;
862 }
863 else
864 {
865 SizeT nCp=Data_::N_Elements();
866
867 // if (non-indexed) src is smaller -> just copy its number of elements
868 if( nCp > srcElem) nCp=srcElem;
869
870 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
871 {
872 //#pragma omp for
873 for( SizeT c=0; c<nCp; ++c)
874 {
875 Ty& a = (*this)[ c];
876 Ty b = (*src)[c];
877 GDLInterpreter::IncRefObj( b);
878 GDLInterpreter::DecRefObj( a);
879 a = b;//(*this)[ c]=(*src)[c];
880 }
881 }
882 }
883 }
884
885
886
887 // returns (*this)[ ixList]
888 template<>
Index(ArrayIndexListT * ixList)889 Data_<SpDPtr>* Data_<SpDPtr>::Index( ArrayIndexListT* ixList)
890 {
891 // ixList->SetVariable( this);
892
893 Data_* res=Data_::New( ixList->GetDim(), BaseGDL::NOZERO);
894
895 SizeT nCp=ixList->N_Elements();
896
897 // cout << "nCP = " << nCp << endl;
898 // cout << "dim = " << this->dim << endl;
899
900 // DataT& res_dd = res->dd;
901 AllIxBaseT* allIx = ixList->BuildIx();
902 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
903 {
904 //#pragma omp for
905 for( SizeT c=0; c<nCp; ++c)
906 {
907 Ty a = (*this)[ (*allIx)[ c]];
908 GDLInterpreter::IncRef(a);
909 (*res)[c]=a;
910 }
911 } // res_(*this)[c]=(*this)[ (*allIx)[ c]];
912 // (*res)[c]=(*this)[ ixList->GetIx(c)];
913
914 return res;
915 }
916 // returns (*this)[ ixList]
917 template<>
Index(ArrayIndexListT * ixList)918 Data_<SpDObj>* Data_<SpDObj>::Index( ArrayIndexListT* ixList)
919 {
920 // ixList->SetVariable( this);
921
922 Data_* res=Data_::New( ixList->GetDim(), BaseGDL::NOZERO);
923
924 SizeT nCp=ixList->N_Elements();
925
926 // cout << "nCP = " << nCp << endl;
927 // cout << "dim = " << this->dim << endl;
928
929 // DataT& res_dd = res->dd;
930 AllIxBaseT* allIx = ixList->BuildIx();
931 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
932 {
933 //#pragma omp for
934 for( SizeT c=0; c<nCp; ++c)
935 {
936 Ty a = (*this)[ (*allIx)[ c]];
937 GDLInterpreter::IncRefObj(a);
938 (*res)[c]=a;
939 }
940 } // res_(*this)[c]=(*this)[ (*allIx)[ c]];
941 // (*res)[c]=(*this)[ ixList->GetIx(c)];
942
943 return res;
944 }
945
946
947
948 // used by AccessDescT for resolving, no checking is done
949 // inserts srcIn[ ixList] at offset
950 // used by DotAccessDescT::DoResolve
951 template<>
InsertAt(SizeT offset,BaseGDL * srcIn,ArrayIndexListT * ixList)952 void Data_<SpDPtr>::InsertAt( SizeT offset, BaseGDL* srcIn,
953 ArrayIndexListT* ixList)
954 {
955 Data_* src=static_cast<Data_* >(srcIn);
956 if( ixList == NULL)
957 {
958 SizeT nCp=src->N_Elements();
959
960 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
961 {
962 //#pragma omp for
963 for( SizeT c=0; c<nCp; ++c)
964 {
965 Ty a = (*this)[ c+offset];
966 Ty b = (*src)[c];
967 GDLInterpreter::IncRef( b);
968 GDLInterpreter::DecRef( a);
969 (*this)[ c+offset]=(*src)[c];
970 }
971 } }
972 else
973 {
974 SizeT nCp=ixList->N_Elements();
975
976 AllIxBaseT* allIx = ixList->BuildIx();
977 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
978 {
979 //#pragma omp for
980 for( SizeT c=0; c<nCp; ++c)
981 {
982 Ty a = (*this)[ c+offset];
983 Ty b = (*src)[ (*allIx)[ c]];
984 GDLInterpreter::IncRef( b);
985 GDLInterpreter::DecRef( a);
986 (*this)[ c+offset]=(*src)[ (*allIx)[ c]];
987 } // (*this)[ c+offset]=(*src)[ ixList->GetIx( c)];
988 }
989 }
990 }
991
992
993 // used for concatenation, called from CatArray
994 // assumes that everything is checked (see CatInfo)
995 template<>
CatInsert(const Data_ * srcArr,const SizeT atDim,SizeT & at)996 void Data_<SpDPtr>::CatInsert( const Data_* srcArr, const SizeT atDim, SizeT& at)
997 {
998 // length of one segment to copy
999 SizeT len=srcArr->dim.Stride(atDim+1); // src array
1000
1001 // number of copy actions
1002 SizeT nCp=srcArr->N_Elements()/len;
1003
1004 // initial offset
1005 SizeT destStart= this->dim.Stride(atDim) * at; // dest array
1006 SizeT destEnd = destStart + len;
1007
1008 // number of elements to skip
1009 SizeT gap=this->dim.Stride(atDim+1); // dest array
1010
1011 #ifdef _OPENMP
1012 SizeT nEl = srcArr->N_Elements();
1013 //#pragma omp parallel for if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl))
1014 for( SizeT c=0; c<nCp; ++c)
1015 {
1016 // set new destination pointer
1017 SizeT eIx = c*gap;
1018 SizeT sIx = eIx + destStart;
1019 eIx += destEnd;
1020
1021 // copy one segment
1022 SizeT srcIx = c*len;
1023 for( SizeT destIx=sIx; destIx< eIx; ++destIx)
1024 {
1025 Ty b = (*srcArr)[ srcIx+destIx-sIx];
1026 GDLInterpreter::IncRef( b);
1027 (*this)[destIx] = (*srcArr)[ srcIx+destIx-sIx];
1028 }
1029 }
1030 #else
1031 SizeT srcIx=0;
1032 for( SizeT c=0; c<nCp; ++c)
1033 {
1034 // copy one segment
1035 for( SizeT destIx=destStart; destIx< destEnd; destIx++)
1036 {
1037 Ty b = (*srcArr)[ srcIx];
1038 GDLInterpreter::IncRef( b);
1039 (*this)[destIx] = (*srcArr)[ srcIx++];
1040 }
1041
1042 // set new destination pointer
1043 destStart += gap;
1044 destEnd += gap;
1045 }
1046 #endif
1047
1048 SizeT add=srcArr->dim[atDim]; // update 'at'
1049 at += (add > 1)? add : 1;
1050 }
1051
1052
1053
1054 // used by AccessDescT for resolving, no checking is done
1055 // inserts srcIn[ ixList] at offset
1056 // used by DotAccessDescT::DoResolve
1057 template<>
InsertAt(SizeT offset,BaseGDL * srcIn,ArrayIndexListT * ixList)1058 void Data_<SpDObj>::InsertAt( SizeT offset, BaseGDL* srcIn,
1059 ArrayIndexListT* ixList)
1060 {
1061 Data_* src=static_cast<Data_* >(srcIn);
1062 if( ixList == NULL)
1063 {
1064 SizeT nCp=src->N_Elements();
1065
1066 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
1067 {
1068 //#pragma omp for
1069 for( SizeT c=0; c<nCp; ++c)
1070 {
1071 Ty a = (*this)[ c+offset];
1072 Ty b = (*src)[c];
1073 GDLInterpreter::IncRefObj( b);
1074 GDLInterpreter::DecRefObj( a);
1075 (*this)[ c+offset]=(*src)[c];
1076 }
1077 } }
1078 else
1079 {
1080 SizeT nCp=ixList->N_Elements();
1081
1082 AllIxBaseT* allIx = ixList->BuildIx();
1083 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
1084 {
1085 //#pragma omp for
1086 for( SizeT c=0; c<nCp; ++c)
1087 {
1088 Ty a = (*this)[ c+offset];
1089 Ty b = (*src)[ (*allIx)[ c]];
1090 GDLInterpreter::IncRefObj( b);
1091 GDLInterpreter::DecRefObj( a);
1092 (*this)[ c+offset]=(*src)[ (*allIx)[ c]];
1093 } // (*this)[ c+offset]=(*src)[ ixList->GetIx( c)];
1094 }
1095 }
1096 }
1097
1098
1099 // used for concatenation, called from CatArray
1100 // assumes that everything is checked (see CatInfo)
1101 template<>
CatInsert(const Data_ * srcArr,const SizeT atDim,SizeT & at)1102 void Data_<SpDObj>::CatInsert( const Data_* srcArr, const SizeT atDim, SizeT& at)
1103 {
1104 // length of one segment to copy
1105 SizeT len=srcArr->dim.Stride(atDim+1); // src array
1106
1107 // number of copy actions
1108 SizeT nCp=srcArr->N_Elements()/len;
1109
1110 // initial offset
1111 SizeT destStart= this->dim.Stride(atDim) * at; // dest array
1112 SizeT destEnd = destStart + len;
1113
1114 // number of elements to skip
1115 SizeT gap=this->dim.Stride(atDim+1); // dest array
1116
1117 #ifdef _OPENMP
1118 SizeT nEl = srcArr->N_Elements();
1119 //#pragma omp parallel for if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl))
1120 for( SizeT c=0; c<nCp; ++c)
1121 {
1122 // set new destination pointer
1123 SizeT eIx = c*gap;
1124 SizeT sIx = eIx + destStart;
1125 eIx += destEnd;
1126
1127 // copy one segment
1128 SizeT srcIx = c*len;
1129 for( SizeT destIx=sIx; destIx< eIx; ++destIx)
1130 {
1131 Ty b = (*srcArr)[ srcIx+destIx-sIx];
1132 GDLInterpreter::IncRefObj( b);
1133 (*this)[destIx] = (*srcArr)[ srcIx+destIx-sIx];
1134 }
1135 }
1136 #else
1137 SizeT srcIx=0;
1138 for( SizeT c=0; c<nCp; ++c)
1139 {
1140 // copy one segment
1141 for( SizeT destIx=destStart; destIx< destEnd; destIx++)
1142 {
1143 Ty b = (*srcArr)[ srcIx];
1144 GDLInterpreter::IncRefObj( b);
1145 (*this)[destIx] = (*srcArr)[ srcIx++];
1146 }
1147
1148 // set new destination pointer
1149 destStart += gap;
1150 destEnd += gap;
1151 }
1152 #endif
1153
1154 SizeT add=srcArr->dim[atDim]; // update 'at'
1155 at += (add > 1)? add : 1;
1156 }
1157
1158
1159
1160 template<>
Assign(BaseGDL * src,SizeT nEl)1161 void Data_<SpDPtr>::Assign( BaseGDL* src, SizeT nEl)
1162 {
1163 // Data_* srcT = dynamic_cast<Data_*>( src);
1164 //
1165 // Guard< Data_> srcTGuard;
1166 // if( srcT == NULL)
1167 // {
1168 // srcT = static_cast<Data_*>( src->Convert2( Data_::t, BaseGDL::COPY));
1169 // srcTGuard.Reset( srcT);
1170 // }
1171 Data_* srcT; // = dynamic_cast<Data_*>( src);
1172
1173 Guard< Data_> srcTGuard;
1174 if( src->Type() != Data_::t)
1175 {
1176 srcT = static_cast<Data_*>( src->Convert2( Data_::t, BaseGDL::COPY));
1177 srcTGuard.Init( srcT);
1178 }
1179 else
1180 {
1181 srcT = static_cast<Data_*>( src);
1182 }
1183
1184 //#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl))
1185 {
1186 //#pragma omp for
1187 for(long k=0; k < nEl; ++k)
1188 {
1189 Ty a = (*this)[ k];
1190 Ty b = (*srcT)[k];
1191 GDLInterpreter::IncRef( b);
1192 GDLInterpreter::DecRef( a);
1193 (*this)[ k] = (*srcT)[ k];
1194 } }
1195 }
1196
1197 template<>
Assign(BaseGDL * src,SizeT nEl)1198 void Data_<SpDObj>::Assign( BaseGDL* src, SizeT nEl)
1199 {
1200 // Data_* srcT = dynamic_cast<Data_*>( src);
1201 //
1202 // Guard< Data_> srcTGuard;
1203 // if( srcT == NULL)
1204 // {
1205 // srcT = static_cast<Data_*>( src->Convert2( Data_::t, BaseGDL::COPY));
1206 // srcTGuard.Reset( srcT);
1207 // }
1208 Data_* srcT; // = dynamic_cast<Data_*>( src);
1209
1210 Guard< Data_> srcTGuard;
1211 if( src->Type() != Data_::t)
1212 {
1213 srcT = static_cast<Data_*>( src->Convert2( Data_::t, BaseGDL::COPY));
1214 srcTGuard.Init( srcT);
1215 }
1216 else
1217 {
1218 srcT = static_cast<Data_*>( src);
1219 }
1220
1221 //#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl))
1222 {
1223 //#pragma omp for
1224 for(long k=0; k < nEl; ++k)
1225 {
1226 Ty a = (*this)[ k];
1227 Ty b = (*srcT)[k];
1228 GDLInterpreter::IncRefObj( b);
1229 GDLInterpreter::DecRefObj( a);
1230 (*this)[ k] = (*srcT)[ k];
1231 } }
1232 }
1233
1234
1235
1236 // return a new type of itself (only for one dimensional case)
1237 template<>
NewIx(SizeT ix)1238 BaseGDL* Data_<SpDPtr>::NewIx( SizeT ix)
1239 {
1240 Ty b = (*this)[ ix];
1241 GDLInterpreter::IncRef( b);
1242 return new Data_( (*this)[ ix]);
1243 }
1244
1245 // return a new type of itself (only for one dimensional case)
1246 template<>
NewIx(SizeT ix)1247 BaseGDL* Data_<SpDObj>::NewIx( SizeT ix)
1248 {
1249 if( !this->StrictScalar())
1250 {
1251 Ty b = (*this)[ ix];
1252 GDLInterpreter::IncRefObj( b);
1253 return new Data_( (*this)[ ix]);
1254 }
1255
1256 DObj s = dd[0]; // is StrictScalar()
1257 if( s == 0) // no overloads for null object
1258 return new Data_( 0);
1259
1260 DStructGDL* oStructGDL= GDLInterpreter::GetObjHeapNoThrow( s);
1261 if( oStructGDL == NULL) // if object not valid -> default behaviour
1262 return new Data_( 0);
1263
1264 DStructDesc* desc = oStructGDL->Desc();
1265
1266 if( desc->IsParent("LIST"))
1267 {
1268 static DString cNodeName("GDL_CONTAINER_NODE");
1269 // because of .RESET_SESSION, we cannot use static here
1270 DStructDesc* containerDesc=structDesc::GDL_CONTAINER_NODE;
1271
1272 // no static here, might vary in derived object
1273 // unsigned pHeadTag = desc->TagIndex( "PHEAD");
1274 static unsigned pTailTag = desc->TagIndex( "PTAIL");
1275
1276 static unsigned pNextTag = structDesc::GDL_CONTAINER_NODE->TagIndex( "PNEXT");
1277 static unsigned pDataTag = structDesc::GDL_CONTAINER_NODE->TagIndex( "PDATA");
1278 // unsigned nListTag = desc->TagIndex( "NLIST");
1279 // SizeT listSize = (*static_cast<DLongGDL*>(oStructGDL->GetTag( nListTag, 0)))[0];
1280
1281 DPtr actP = (*static_cast<DPtrGDL*>(oStructGDL->GetTag( pTailTag, 0)))[0];
1282 for( SizeT elIx = 0; elIx < ix; ++elIx)
1283 {
1284 BaseGDL* actPHeap = BaseGDL::interpreter->GetHeap( actP);
1285 if( actPHeap->Type() != GDL_STRUCT)
1286 throw GDLException( "LIST node must be a STRUCT.");
1287 DStructGDL* actPStruct = static_cast<DStructGDL*>( actPHeap);
1288 if( actPStruct->Desc() != containerDesc)
1289 throw GDLException( "LIST node must be a GDL_CONTAINER_NODE STRUCT.");
1290
1291 actP = (*static_cast<DPtrGDL*>( actPStruct->GetTag( pNextTag, 0)))[0];
1292 }
1293
1294 BaseGDL* actPHeap = BaseGDL::interpreter->GetHeap( actP);
1295 if( actPHeap->Type() != GDL_STRUCT)
1296 throw GDLException( "LIST node must be a STRUCT.");
1297 DStructGDL* actPStruct = static_cast<DStructGDL*>( actPHeap);
1298 if( actPStruct->Desc() != containerDesc)
1299 throw GDLException( "LIST node must be a GDL_CONTAINER_NODE STRUCT.");
1300
1301 actP = (*static_cast<DPtrGDL*>(actPStruct->GetTag( pDataTag, 0)))[0];
1302
1303 BaseGDL* result = BaseGDL::interpreter->GetHeap( actP);
1304 if( result == NULL)
1305 return NullGDL::GetSingleInstance();
1306 return result->Dup();
1307 }
1308 if( desc->IsParent("HASH"))
1309 {
1310 static DString hashName("HASH");
1311 static DString entryName("GDL_HASHTABLEENTRY");
1312 static unsigned pDataTag = structDesc::HASH->TagIndex( "TABLE_DATA");
1313 static unsigned nSizeTag = structDesc::HASH->TagIndex( "TABLE_SIZE");
1314 static unsigned nCountTag = structDesc::HASH->TagIndex( "TABLE_COUNT");
1315 static unsigned nForEachTag = structDesc::HASH->TagIndex( "TABLE_FOREACH");
1316 static unsigned pKeyTag = structDesc::GDL_HASHTABLEENTRY->TagIndex( "PKEY");
1317 static unsigned pValueTag = structDesc::GDL_HASHTABLEENTRY->TagIndex( "PVALUE");
1318
1319 DPtr pHashTable = (*static_cast<DPtrGDL*>( oStructGDL->GetTag( pDataTag, 0)))[0];
1320 DStructGDL* hashTable = static_cast<DStructGDL*>(BaseGDL::interpreter->GetHeap( pHashTable));
1321
1322 DLong validIx = 0;
1323 DLong i = 0;
1324 for(; i<hashTable->N_Elements(); ++i)
1325 {
1326 DPtr pKey = (*static_cast<DPtrGDL*>(hashTable->GetTag( pKeyTag, i)))[0];
1327 if( pKey != 0)
1328 {
1329 if( validIx == ix)
1330 break;
1331 ++validIx;
1332 }
1333 }
1334 assert( i<hashTable->N_Elements());
1335
1336 DPtr pValue = (*static_cast<DPtrGDL*>(hashTable->GetTag( pValueTag, i)))[0];
1337 DPtr pKey = (*static_cast<DPtrGDL*>(hashTable->GetTag( pKeyTag, i)))[0];
1338
1339 (*static_cast<DULongGDL*>( oStructGDL->GetTag( nForEachTag, 0)))[0] = pKey;
1340
1341 BaseGDL* result = BaseGDL::interpreter->GetHeap( pValue);
1342 if( result == NULL)
1343 return NullGDL::GetSingleInstance();
1344 return result->Dup();
1345 }
1346
1347 GDLInterpreter::IncRefObj( s);
1348 return new Data_( s);
1349 }
1350
1351
1352
1353 template<>
NewIx(AllIxBaseT * ix,const dimension * dIn)1354 Data_<SpDPtr>* Data_<SpDPtr>::NewIx( AllIxBaseT* ix, const dimension* dIn)
1355 {
1356 SizeT nCp = ix->size();
1357 Data_* res=Data_::New( *dIn, BaseGDL::NOZERO);
1358 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
1359 {
1360 //#pragma omp for
1361 for( SizeT c=0; c<nCp; ++c)
1362 {
1363 Ty b = (*this)[ (*ix)[ c]];
1364 GDLInterpreter::IncRef( b);
1365 (*res)[c]=(*this)[ (*ix)[ c]];
1366 }
1367 }
1368 return res;
1369 }
1370 template<>
NewIx(AllIxBaseT * ix,const dimension * dIn)1371 Data_<SpDObj>* Data_<SpDObj>::NewIx( AllIxBaseT* ix, const dimension* dIn)
1372 {
1373 SizeT nCp = ix->size();
1374 Data_* res=Data_::New( *dIn, BaseGDL::NOZERO);
1375 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
1376 {
1377 //#pragma omp for
1378 for( SizeT c=0; c<nCp; ++c)
1379 {
1380 Ty b = (*this)[ (*ix)[ c]];
1381 GDLInterpreter::IncRefObj( b);
1382 (*res)[c]=(*this)[ (*ix)[ c]];
1383 }
1384 }
1385 return res;
1386 }
1387
1388 template<>
NewIxFrom(SizeT s)1389 Data_<SpDPtr>* Data_<SpDPtr>::NewIxFrom( SizeT s)
1390 {
1391 SizeT nCp = dd.size() - s;
1392 Data_* res=Data_::New( dimension( nCp), BaseGDL::NOZERO);
1393 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
1394 {
1395 //#pragma omp for
1396 for( SizeT c=0; c<nCp; ++c)
1397 {
1398 Ty b = (*this)[ s+c];
1399 GDLInterpreter::IncRef( b);
1400 (*res)[c]=(*this)[ s+c];
1401 }
1402 }
1403 return res;
1404 }
1405 template<>
NewIxFrom(SizeT s)1406 Data_<SpDObj>* Data_<SpDObj>::NewIxFrom( SizeT s)
1407 {
1408 SizeT nCp = dd.size() - s;
1409 Data_* res=Data_::New( dimension( nCp), BaseGDL::NOZERO);
1410 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
1411 {
1412 //#pragma omp for
1413 for( SizeT c=0; c<nCp; ++c)
1414 {
1415 Ty b = (*this)[ s+c];
1416 GDLInterpreter::IncRefObj( b);
1417 (*res)[c]=(*this)[ s+c];
1418 }
1419 }
1420 return res;
1421 }
1422
1423 template<>
NewIxFrom(SizeT s,SizeT e)1424 Data_<SpDPtr>* Data_<SpDPtr>::NewIxFrom( SizeT s, SizeT e)
1425 {
1426 SizeT nCp = e - s + 1;
1427 Data_* res=Data_::New( dimension( nCp), BaseGDL::NOZERO);
1428 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
1429 {
1430 //#pragma omp for
1431 for( SizeT c=0; c<nCp; ++c)
1432 {
1433 Ty b = (*this)[ s+c];
1434 GDLInterpreter::IncRef( b);
1435 (*res)[c]=(*this)[ s+c];
1436 }
1437 }
1438 return res;
1439 }
1440
1441 template<>
NewIxFrom(SizeT s,SizeT e)1442 Data_<SpDObj>* Data_<SpDObj>::NewIxFrom( SizeT s, SizeT e)
1443 {
1444 SizeT nCp = e - s + 1;
1445 Data_* res=Data_::New( dimension( nCp), BaseGDL::NOZERO);
1446 //#pragma omp parallel if (nCp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCp))
1447 {
1448 //#pragma omp for
1449 for( SizeT c=0; c<nCp; ++c)
1450 {
1451 Ty b = (*this)[ s+c];
1452 GDLInterpreter::IncRefObj( b);
1453 (*res)[c]=(*this)[ s+c];
1454 }
1455 }
1456 return res;
1457 }
1458
1459 template<>
NewIxFromStride(SizeT s,SizeT stride)1460 Data_<SpDPtr>* Data_<SpDPtr>::NewIxFromStride( SizeT s, SizeT stride)
1461 {
1462 SizeT nCp = (dd.size() - s + stride - 1)/stride;
1463 Data_* res=Data_::New( dimension( nCp), BaseGDL::NOZERO);
1464 for( SizeT c=0; c<nCp; ++c, s += stride)
1465 {
1466 Ty b = (*this)[ s];
1467 GDLInterpreter::IncRef( b);
1468 (*res)[c]=(*this)[ s];
1469 }
1470 return res;
1471 }
1472 template<>
NewIxFromStride(SizeT s,SizeT e,SizeT stride)1473 Data_<SpDPtr>* Data_<SpDPtr>::NewIxFromStride( SizeT s, SizeT e, SizeT stride)
1474 {
1475 SizeT nCp = (e - s + stride)/stride;
1476 Data_* res=Data_::New( dimension( nCp), BaseGDL::NOZERO);
1477 for( SizeT c=0; c<nCp; ++c, s += stride)
1478 {
1479 Ty b = (*this)[ s];
1480 GDLInterpreter::IncRef( b);
1481 (*res)[c]=(*this)[ s];
1482 }
1483 return res;
1484 }
1485
1486 template<>
NewIxFromStride(SizeT s,SizeT stride)1487 Data_<SpDObj>* Data_<SpDObj>::NewIxFromStride( SizeT s, SizeT stride)
1488 {
1489 SizeT nCp = (dd.size() - s + stride - 1)/stride;
1490 Data_* res=Data_::New( dimension( nCp), BaseGDL::NOZERO);
1491 for( SizeT c=0; c<nCp; ++c, s += stride)
1492 {
1493 Ty b = (*this)[ s];
1494 GDLInterpreter::IncRefObj( b);
1495 (*res)[c]=(*this)[ s];
1496 }
1497 return res;
1498 }
1499 template<>
NewIxFromStride(SizeT s,SizeT e,SizeT stride)1500 Data_<SpDObj>* Data_<SpDObj>::NewIxFromStride( SizeT s, SizeT e, SizeT stride)
1501 {
1502 SizeT nCp = (e - s + stride)/stride;
1503 Data_* res=Data_::New( dimension( nCp), BaseGDL::NOZERO);
1504 for( SizeT c=0; c<nCp; ++c, s += stride)
1505 {
1506 Ty b = (*this)[ s];
1507 GDLInterpreter::IncRefObj( b);
1508 (*res)[c]=(*this)[ s];
1509 }
1510 return res;
1511 }
1512
1513
1514
1515
1516
1517
1518 #undef NEWIX_SIGNEDINT
1519 #undef NEWIX_UNSIGNEDINT
1520 #define NEWIX_UNSIGNEDINT \
1521 SizeT i = 0; \
1522 for( ; i < nElem; ++i) \
1523 if( (*src)[i] > upper) \
1524 { \
1525 if( strict) \
1526 throw GDLException("Array used to subscript array " \
1527 "contains out of range (>) subscript."); \
1528 (*res)[i++]= upperVal; \
1529 break; \
1530 } \
1531 else \
1532 (*res)[i]= (*this)[ (*src)[i]]; \
1533 for(; i < nElem; ++i) \
1534 if( (*src)[i] > upper) \
1535 (*res)[i] = upperVal; \
1536 else \
1537 (*res)[i]= (*this)[ (*src)[i]]; \
1538 GDLInterpreter::IncRef( res); \
1539 return guard.release();
1540
1541 #define NEWIX_SIGNEDINT \
1542 SizeT i = 0; \
1543 for(; i < nElem; ++i) \
1544 if( (*src)[i] < 0) \
1545 { \
1546 if( strict) \
1547 throw GDLException("Array used to subscript array " \
1548 "contains out of range (<0) subscript."); \
1549 (*res)[i++]= zeroVal; \
1550 break; \
1551 } \
1552 else if( (*src)[i] > upper) \
1553 { \
1554 if( strict) \
1555 throw GDLException("Array used to subscript array " \
1556 "contains out of range (>) subscript."); \
1557 (*res)[i++]= upperVal; \
1558 break; \
1559 } \
1560 else \
1561 (*res)[ i] = (*this)[ (*src)[ i]]; \
1562 for(; i < nElem; ++i) \
1563 if( (*src)[i] < 0) \
1564 (*res)[i]= zeroVal; \
1565 else if( (*src)[i] > upper) \
1566 (*res)[i]= upperVal; \
1567 else \
1568 (*res)[ i] = (*this)[ (*src)[ i]]; \
1569 GDLInterpreter::IncRef( res); \
1570 return guard.release();
1571
1572 template<>
NewIx(BaseGDL * ix,bool strict)1573 Data_<SpDPtr>* Data_<SpDPtr>::NewIx( BaseGDL* ix, bool strict)
1574 {
1575
1576 assert( ix->Type() != GDL_UNDEF);
1577
1578 // no type checking needed here: GetAsIndex() will fail with grace
1579 // int typeCheck = DTypeOrder[ dType];
1580 // if( typeCheck >= 100)
1581 // throw GDLException("Type "+ix->TypeStr()+" not allowed as subscript.");
1582
1583 SizeT nElem = ix->N_Elements();
1584
1585 Data_* res = New( ix->Dim(), BaseGDL::NOZERO);
1586 Guard<Data_> guard( res);
1587
1588 SizeT upper = dd.size() - 1;
1589 Ty upperVal = (*this)[ upper];
1590 if( strict)
1591 {
1592 for(SizeT i = 0 ; i < nElem; ++i)
1593 {
1594 SizeT actIx = ix->GetAsIndexStrict( i);
1595 if( actIx > upper)
1596 throw GDLException("Array used to subscript array "
1597 "contains out of range (>) subscript (at index: "+i2s(i)+").");
1598 (*res)[i]= (*this)[ actIx];
1599 }
1600 }
1601 else // not strict
1602 {
1603 for(SizeT i = 0 ; i < nElem; ++i)
1604 {
1605 SizeT actIx = ix->GetAsIndex( i);
1606 if( actIx >= upper)
1607 (*res)[i] = upperVal;
1608 else
1609 (*res)[i]= (*this)[ actIx];
1610 }
1611 }
1612 GDLInterpreter::IncRef( res);
1613 return guard.release();
1614 }
1615
1616
1617
1618 template<>
NewIx(BaseGDL * ix,bool strict)1619 Data_<SpDObj>* Data_<SpDObj>::NewIx( BaseGDL* ix, bool strict)
1620 {
1621 SizeT nElem = ix->N_Elements();
1622
1623 Data_* res = New( ix->Dim(), BaseGDL::NOZERO);
1624 Guard<Data_> guard( res);
1625
1626 SizeT upper = dd.size() - 1;
1627 Ty upperVal = (*this)[ upper];
1628 if( strict)
1629 {
1630 for(SizeT i = 0 ; i < nElem; ++i)
1631 {
1632 SizeT actIx = ix->GetAsIndexStrict( i);
1633 if( actIx > upper)
1634 throw GDLException("Array used to subscript array "
1635 "contains out of range (>) subscript (at index: "+i2s(i)+").");
1636 (*res)[i]= (*this)[ actIx];
1637 }
1638 }
1639 else // not strict
1640 {
1641 for(SizeT i = 0 ; i < nElem; ++i)
1642 {
1643 SizeT actIx = ix->GetAsIndex( i);
1644 if( actIx >= upper)
1645 (*res)[i] = upperVal;
1646 else
1647 (*res)[i]= (*this)[ actIx];
1648 }
1649 }
1650 GDLInterpreter::IncRefObj( res);
1651 return guard.release();
1652 }
1653
1654 #endif
1655