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