1 /***************************************************************************
2                           dstructgdl.hpp  -  GDL struct datatype
3                              -------------------
4     begin                : July 22 2002
5     copyright            : (C) 2002 by Marc Schellens
6     email                : m_schellens@users.sf.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef dstructgdl_hpp_
19 #define dstructgdl_hpp_
20 
21 #include <string>
22 // #include <deque>
23 
24 #include "typedefs.hpp"
25 #include "datatypes.hpp" // for friend declaration
26 //#include "typetraits.hpp"
27 #include "dstructdesc.hpp"
28 
29 // NOTE: lot of the code together with Data_<...>::functions
30 // does not fit really into the template because of different
31 // constructor
32 // also here a vector is used instead of a valarray
33 
34 class DStructGDL: public SpDStruct
35 {
36 public:
37   typedef SpDStruct::Ty    Ty;
38   typedef SpDStruct        Traits;
39 
40 private:
41 
42   typedef SpDStruct::DataT DataT;
43 
44   //public:
45   std::vector<BaseGDL*> typeVar;   // for accessing data
46 #ifdef USE_EIGEN
47   EIGEN_ALIGN16 DataT        dd; // the data
48 #else
49   DataT                      dd; // the data
50 #endif
51 
InitTypeVar(SizeT t)52   void InitTypeVar( SizeT t)
53   {
54     typeVar[ t] = (*Desc())[ t]->GetEmptyInstance();
55     typeVar[ t]->SetBufferSize( (*Desc())[ t]->N_Elements());
56     // no initial SetBuffer here, done anyway in ConstructTag()
57   }
58 
Buf() const59   const char* Buf() const { return &dd[0];}
Buf()60   char*       Buf()       { return &dd[0];}
61 
62 public:
63 
64   static std::vector< void*> freeList;
65 
66   // operator new and delete
67   static void* operator new( size_t bytes);
68   static void operator delete( void *ptr);
69 
70   //structors
71   ~DStructGDL();
72 
73   // default (needed for test instantiation)
74   //  DStructGDL(): SpDStruct(), d() {}
75 
76   // new array (desc defined)
DStructGDL(DStructDesc * desc_,const dimension & dim_)77   DStructGDL( DStructDesc* desc_, const dimension& dim_)
78     : SpDStruct( desc_, dim_)
79     , typeVar( desc_->NTags())
80     , dd( dim.NDimElements() * desc_->NBytes(), false) //,SpDStruct::zero)
81   {
82     dim.Purge();
83 
84     SizeT nTags = NTags();
85     for( SizeT t=0; t < nTags; ++t)
86       {
87 	InitTypeVar( t);
88 	ConstructTagTo0( t);
89       }
90   }
91   // new array (desc defined), don't init fields (only for New())
92   // (non POD must be initialized (constructed) nevertheless)
93   // or no memeory allocation
DStructGDL(DStructDesc * desc_,const dimension & dim_,BaseGDL::InitType iT)94   DStructGDL( DStructDesc* desc_, const dimension& dim_, BaseGDL::InitType iT)
95     : SpDStruct( desc_, dim_)
96     , typeVar( desc_->NTags())
97     , dd( (iT == BaseGDL::NOALLOC) ? 0 : dim.NDimElements() * desc_->NBytes(),
98 	  false)
99   {
100     assert( iT == BaseGDL::NOZERO || iT == BaseGDL::NOALLOC);
101     dim.Purge();
102 
103     if( iT != BaseGDL::NOALLOC)
104       {
105 	SizeT nTags = NTags();
106 // 	SizeT nEl   = dim.N_Elements();
107 	for( SizeT t=0; t < nTags; ++t)
108 	  {
109 	    InitTypeVar( t);
110 	    ConstructTag( t);
111 	  }
112       }
113     else // iT == BaseGDL::NOALLOC
114       {
115 	SizeT nTags = NTags();
116 	for( SizeT t=0; t < nTags; ++t)
117 	  {
118 	    InitTypeVar( t);
119 	  }
120       }
121   }
122 
123   // c-i (desc defined)
124   // only called from Assoc_'s c-i
125   DStructGDL(const DStructGDL& d_);
126 
127   // For creating new structs (always scalar)
DStructGDL(DStructDesc * desc_)128   DStructGDL( DStructDesc* desc_)
129     : SpDStruct(desc_, dimension(1))
130     , typeVar()
131     , dd()
132   {
133     assert( desc_->NTags() == 0);
134 //     SizeT nTags = NTags();
135 //     for( SizeT t=0; t < nTags; ++t)
136 //       {
137 // 	InitTypeVar( t);
138 //       }
139   }
140   // new struct (always scalar), creating new descriptor
141   // intended for internal (C++) use to ease struct definition
142   // ATTENTION: This can only be used for NAMED STRUCTS!
143   // please use the normal constructor (above) for unnamed structs
144   DStructGDL( const std::string& name_);
145 
146 
147   // operators
148 
149   // assignment.
operator =(const BaseGDL & r)150   DStructGDL& operator=(const BaseGDL& r)
151   {
152     assert( r.Type() == GDL_STRUCT);
153     const DStructGDL& right = static_cast<const DStructGDL&>( r);
154 
155     assert( *Desc() == *right.Desc());
156 
157     assert( &right != this);
158     if( &right == this) return *this; // self assignment
159 
160     this->dim = right.dim;
161 
162     SizeT nTags = NTags();
163     SizeT nEl   = N_Elements();
164     for( SizeT e=0; e < nEl; ++e)
165     for( SizeT t=0; t < nTags; ++t)
166       {
167 	*GetTag( t, e) = *right.GetTag( t, e);
168       }
169 
170     return *this;
171   }
172 
InitFrom(const BaseGDL & r)173   void InitFrom(const BaseGDL& r)
174   {
175     assert( r.Type() == GDL_STRUCT);
176     const DStructGDL& right = static_cast<const DStructGDL&>( r);
177 
178     assert( *Desc() == *right.Desc());
179     assert( &right != this);
180 
181     this->dim = right.dim;
182 
183     SizeT nTags = NTags();
184     SizeT nEl   = N_Elements();
185     for( SizeT e=0; e < nEl; ++e)
186 		for( SizeT t=0; t < nTags; ++t)
187 		{
188 			GetTag( t, e)->InitFrom( *right.GetTag( t, e));
189 		}
190   }
191 
operator [](const SizeT d1)192   inline BaseGDL* operator[] (const SizeT d1)
193   {
194     return GetTag( d1 % NTags(), d1 / NTags());
195   }
operator [](const SizeT d1) const196   inline const BaseGDL* operator[] (const SizeT d1) const
197   {
198     return GetTag( d1 % NTags(), d1 / NTags());
199   }
200 
201 // void* DataAddr( SizeT elem)
202 // {
203 // return &(*this)[elem];
204 // }
DataAddr()205 void* DataAddr()// SizeT elem)
206 {
207 if( Buf() == NULL)
208   throw GDLException("DStructGDL: Data not set.");
209 return Buf();
210 }//elem];}
DataAddr(SizeT tag)211 void* DataAddr(SizeT tag)// SizeT elem)
212 {
213 if( dd.size() == 0) return typeVar[ t];
214 return Buf();
215 }//elem];}
216 
217   // used for named struct definition
218   // (GDLInterpreter, basic_fun (create_struct))
219   void SetDesc( DStructDesc* newDesc);
220 
221    DStructGDL* SetBuffer( const void* b);
222   void SetBufferSize( SizeT s);
223 
224   DStructGDL* CShift( DLong d) const;
225   DStructGDL* CShift( DLong d[MAXRANK]) const;
226 
227   // for use by MIN and MAX functions
228   void MinMax( DLong* minE, DLong* maxE,
229 	       BaseGDL** minVal, BaseGDL** maxVal, bool omitNaN,
230            SizeT start, SizeT stop, SizeT step, DLong valIx, bool useAbs);
231 
232   //  const DType   Type()    const { return SpDStruct::t;}
233   //  const std::string& TypeStr() const { return SpDStruct::str;}
EqType(const BaseGDL * r) const234   bool          EqType( const BaseGDL* r) const
235   { return (SpDStruct::t == r->Type());}
236 
N_Elements() const237   SizeT N_Elements() const
238   {
239     if( dd.size() == 0) return 1;
240     return dd.size()/Sizeof();
241   }
Size() const242   SizeT Size() const { return N_Elements();}
NBytes() const243   SizeT NBytes() const // for assoc function
244   {
245     return (Sizeof() * N_Elements());
246   }
ToTransfer() const247   SizeT ToTransfer() const // number of elements for IO transfer
248   {
249     SizeT nB = 0;
250     SizeT nTags=NTags();
251     for( SizeT i=0; i < nTags; i++)
252       {
253 	nB += GetTag( i)->ToTransfer();
254       }
255     return ( nB * N_Elements()); // *** error for string?
256   }
NBytesToTransfer()257 SizeT NBytesToTransfer() // number of elements for IO transfer without padding
258 {
259   SizeT nB = 0;
260   SizeT nTags=this->NTags();
261   for( SizeT j=0; j < this->N_Elements(); j++) { //eventually with no error for variable-length strings (in output, input will never work)
262     for( SizeT i=0; i < nTags; i++)
263     {
264       if (this->GetTag(i,j)->Type()==GDL_STRUCT) {
265         DStructGDL* str= static_cast<DStructGDL*>(this->GetTag( i, j));
266         nB += str->NBytesToTransfer();} else nB += this->GetTag( i, j)->NBytes();
267     }
268   }
269   return nB ;
270 }
Sizeof() const271   SizeT Sizeof() const
272   {
273     return Desc()->NBytes();
274 //     SizeT nB = 0;
275 //     SizeT nTags=NTags();
276 //     for( SizeT i=0; i < nTags; i++)
277 //       {
278 // 	nB += desc->GetTag( &dd[0], i)->NBytes();
279 //       }
280 //     return nB;
281   }
SizeofTags() const282   SizeT SizeofTags() const
283   {
284      SizeT nB = 0;
285      SizeT nTags=NTags();
286      for( SizeT i=0; i < nTags; i++)
287        {
288  	       nB += this->GetTag(i)->NBytes();
289        }
290      return nB;
291   }
292 private:
ClearTag(SizeT t)293   void ClearTag( SizeT t)
294   {
295   if( dd.size() == 0)
296 	{
297 	typeVar[ t]->Clear();
298 	}
299   else
300   {
301     char*    offs = Buf() + Desc()->Offset( t);
302     BaseGDL* tVar  = typeVar[ t];
303     SizeT step    = Desc()->NBytes();
304     SizeT endIx = step * N_Elements();
305     for( SizeT ix=0; ix<endIx; ix+=step)
306       {
307 	tVar->SetBuffer( offs + ix)->Clear();
308       }
309   }
310   }
ConstructTagTo0(SizeT t)311   void ConstructTagTo0( SizeT t)
312   {
313     char*    offs = Buf() + Desc()->Offset( t);
314     BaseGDL* tVar  = typeVar[ t];
315     SizeT step = Desc()->NBytes();
316     SizeT endIx = step * N_Elements();
317     for( SizeT ix=0; ix<endIx; ix+=step)
318       {
319 	tVar->SetBuffer( offs + ix)->ConstructTo0();
320       }
321   }
ConstructTag(SizeT t)322   void ConstructTag( SizeT t)
323   {
324     BaseGDL* tVar  = typeVar[ t];
325     if( NonPODType( tVar->Type()))
326       {
327 	char* offs = Buf() + Desc()->Offset( t);
328 	SizeT step = Desc()->NBytes();
329 	SizeT endIx = step * N_Elements();
330 	for( SizeT ix=0; ix<endIx; ix+=step)
331 	  {
332 	    tVar->SetBuffer( offs + ix)->Construct();
333 	  }
334       }
335     else
336       tVar->SetBuffer( Buf() + Desc()->Offset( t));
337 
338   }
DestructTag(SizeT t)339   void DestructTag( SizeT t)
340   {
341     BaseGDL* tVar  = typeVar[ t];
342     if( NonPODType( tVar->Type()))
343       {
344 	char* offs = Buf() + Desc()->Offset( t);
345 	SizeT step = Desc()->NBytes();
346 	SizeT endIx = step * N_Elements();
347 	for( SizeT ix=0; ix<endIx; ix+=step)
348 	  {
349 	    tVar->SetBuffer( offs + ix)->Destruct();
350 	  }
351       }
352   }
353 
354 public:
Clear()355   void Clear()
356   {
357     SizeT nTags = NTags();
358     for( SizeT t=0; t < nTags; t++)
359       {
360 	ClearTag( t);
361       }
362   }
ConstructTo0()363   void ConstructTo0()
364   {
365     SizeT nTags = NTags();
366     for( SizeT t=0; t < nTags; t++)
367       {
368 	ConstructTagTo0( t);
369       }
370   }
Construct()371   void Construct()
372   {
373     SizeT nTags = NTags();
374     for( SizeT t=0; t < nTags; t++)
375       {
376 	ConstructTag( t);
377       }
378   }
Destruct()379   void Destruct()
380   {
381     SizeT nTags = NTags();
382     for( SizeT t=0; t < nTags; t++)
383       {
384 	DestructTag( t);
385       }
386   }
387 
388   // code in default_io.cpp
389   BaseGDL* AssocVar( int, SizeT);
390 
391   // single element access.
392 //   BaseGDL*& Get( SizeT tag, SizeT ix)
GetTag(SizeT t,SizeT ix)393   BaseGDL* GetTag( SizeT t, SizeT ix)
394   {
395     if( dd.size() == 0) return typeVar[ t];
396     return typeVar[ t]->SetBuffer( Buf() + Desc()->Offset( t, ix));
397   }
GetTag(SizeT t)398   BaseGDL* GetTag( SizeT t)
399   {
400     if( dd.size() == 0) return typeVar[ t];
401     return typeVar[ t]->SetBuffer( Buf() + Desc()->Offset( t));
402   }
GetTag(SizeT t,SizeT ix) const403   const BaseGDL* GetTag( SizeT t, SizeT ix) const
404   {
405     if( dd.size() == 0) return typeVar[ t];
406     return typeVar[ t]->SetBuffer( Buf() + Desc()->Offset( t, ix));
407   }
GetTag(SizeT t) const408   const BaseGDL* GetTag( SizeT t) const
409   {
410     if( dd.size() == 0) return typeVar[ t];
411     return typeVar[ t]->SetBuffer( Buf() + Desc()->Offset( t));
412   }
413 
414   // single tag access.
415   BaseGDL* Get( SizeT tag);
416 
417   //***
418 //   friend std::ostream& operator<<(std::ostream& o, DStructGDL& data_);
419   friend std::istream& operator>>(std::istream& i, DStructGDL& data_);
420 
421   std::ostream& ToStream(std::ostream& o, SizeT width = 0, SizeT* actPosPtr = NULL);
422   //  std::ostream& ToStream(std::ostream& o)
423   //  { o << *this; return o;}
424   std::ostream& ToStreamRaw(std::ostream& o);
425 
FromStream(std::istream & i)426   std::istream& FromStream(std::istream& i)
427   { i >> *this; return i;}
428 
429 
430   void AddParent( DStructDesc* p);
431 
432 // private:
433 //   void AddTag( const BaseGDL* data);     // adds copy of data
434 //   void AddTagGrab(BaseGDL* data); // adds data (only used by ExtraT)
435 //  friend class ExtraT;
436 
437 public:
438   // adds data, grabs, adds also to descriptor (for initialization only)
439   // note that initialization is only for scalars
440   void NewTag( const std::string& tName, BaseGDL* data);
441 
442   // for easier internal (c++) usage
443   template< class DataGDL>
InitTag(const std::string & tName,const DataGDL & data)444   void InitTag(const std::string& tName, const DataGDL& data)
445   {
446     int tIx = Desc()->TagIndex( tName);
447     if( tIx == -1)
448       throw GDLException("Struct "+Desc()->Name()+
449 			 " does not contain tag "+tName+".");
450 
451     assert( GetTag( tIx)->N_Elements() == data.N_Elements());
452 
453     // SA: removed, apparently unnecessary, static_cast() which was causing
454     //     numerous compiler (e.g., i686-apple-darwin9-g++-4.0.1) warnings, e.g.:
455     //
456     //     warning: inline function
457     //       'Data_<SpDULong>& Data_<SpDULong>::operator=(const Data_<SpDULong>&)'
458     //       used but never defined
459     //
460     //static_cast<DataGDL&>( *GetTag( tIx)) = data; // copy data
461     GetTag( tIx)->InitFrom( data); // copy data
462   }
463 
464   // members
465   // used by the interpreter
466   // throws (datatypes.cpp)
467   int Scalar2Index( SizeT& st) const;
468   int Scalar2RangeT( RangeT& st) const;
469   RangeT LoopIndex() const;
470 
Scalar() const471   bool Scalar() const
472   { return (N_Elements() == 1);}
473 
474   // make a duplicate on the heap
Dup() const475   BaseGDL* Dup() const { return new DStructGDL(*this);}
476 
New(const dimension & dim_,BaseGDL::InitType noZero=BaseGDL::ZERO) const477 DStructGDL* New ( const dimension& dim_,
478                   BaseGDL::InitType noZero=BaseGDL::ZERO ) const
479 {
480 // No NOZERO for structs
481 	if ( noZero == BaseGDL::NOZERO )
482 	{
483 		DStructGDL* res = new DStructGDL ( Desc(), dim_, noZero );
484 		res->MakeOwnDesc();
485 		return res;
486 	}
487 	if ( noZero == BaseGDL::INIT )
488 	{
489 		DStructGDL* res =  new DStructGDL ( Desc(), dim_, BaseGDL::NOZERO );
490 		res->MakeOwnDesc();
491 		SizeT nEl = res->N_Elements();
492 		SizeT nTags = NTags();
493 		for ( SizeT t=0; t<nTags; ++t )
494 		{
495 			const BaseGDL& cpTag = *GetTag ( t );
496 			for ( SizeT i=0; i<nEl; ++i )
497 				res->GetTag ( t, i )->InitFrom( cpTag);
498 			// 	      res->dd[ i] = dd[ i % nTags]->Dup();
499 		}
500 		return res;
501 	}
502 	DStructGDL* res = new DStructGDL ( Desc(), dim_ );
503 	res->MakeOwnDesc();
504 	return res;
505 }
NewResult() const506 DStructGDL* NewResult() const
507 {
508 	DStructGDL* res = new DStructGDL ( Desc(), this->dim, BaseGDL::NOZERO);
509 	res->MakeOwnDesc();
510 	return res;
511 }
512 
513   // used by interpreter, calls CatInsert
514   DStructGDL* CatArray( ExprListT& exprList,
515 			const SizeT catRank,
516 			const SizeT rank);
517 
518   template< typename To> typename Data_<To>::Ty GetAs( SizeT i);
519 
520   BaseGDL* Convert2( DType destTy,
521 		     BaseGDL::Convert2Mode mode = BaseGDL::CONVERT);
522 
523 #if (defined( TEMPLATE_FRIEND_OK_) || (__GNUC__ >= 4)) && (!__clang__)
524   // make all other Convert2 functions friends
525   template<class Sp2>
526   friend BaseGDL* Data_<Sp2>::Convert2( DType destTy,
527 					BaseGDL::Convert2Mode);
528 #else
529   // this explicit version should work in all cases
530   friend BaseGDL* Data_<SpDByte>::Convert2( DType destTy, BaseGDL::Convert2Mode);
531   friend BaseGDL* Data_<SpDInt>::Convert2( DType destTy, BaseGDL::Convert2Mode);
532   friend BaseGDL* Data_<SpDUInt>::Convert2( DType destTy, BaseGDL::Convert2Mode);
533   friend BaseGDL* Data_<SpDLong>::Convert2( DType destTy, BaseGDL::Convert2Mode);
534   friend BaseGDL* Data_<SpDULong>::Convert2( DType destTy, BaseGDL::Convert2Mode);
535   friend BaseGDL* Data_<SpDLong64>::Convert2( DType destTy, BaseGDL::Convert2Mode);
536   friend BaseGDL* Data_<SpDULong64>::Convert2( DType destTy, BaseGDL::Convert2Mode);
537   friend BaseGDL* Data_<SpDFloat>::Convert2( DType destTy, BaseGDL::Convert2Mode);
538   friend BaseGDL* Data_<SpDDouble>::Convert2( DType destTy, BaseGDL::Convert2Mode);
539   friend BaseGDL* Data_<SpDString>::Convert2( DType destTy, BaseGDL::Convert2Mode);
540   friend BaseGDL* Data_<SpDPtr>::Convert2( DType destTy, BaseGDL::Convert2Mode);
541   friend BaseGDL* Data_<SpDObj>::Convert2( DType destTy, BaseGDL::Convert2Mode);
542   friend BaseGDL* Data_<SpDComplex>::Convert2( DType destTy, BaseGDL::Convert2Mode);
543   friend BaseGDL* Data_<SpDComplexDbl>::Convert2( DType destTy, BaseGDL::Convert2Mode);
544 
545 #endif
546 
547   std::ostream& Write( std::ostream& os, bool swapEndian, bool compress,
548 		       XDR *xdrs);
549   std::istream& Read( std::istream& os, bool swapEndian, bool compress,
550 		      XDR *xdrs);
551 
True()552   bool True()
553   { throw GDLException("Struct expression not allowed in this context.");}
False()554   bool False()
555   { throw GDLException("Struct expression not allowed in this context.");}
LogTrue()556   bool LogTrue()
557   { throw GDLException("Struct expression not allowed in this context.");}
LogTrue(SizeT ix)558   bool LogTrue( SizeT ix)
559   { throw GDLException("Struct expression not allowed in this context.");}
Where(DLong * & ret,SizeT & passed_count,bool comp,DLong * & comp_ret)560   void Where(DLong* &ret, SizeT &passed_count, bool comp, DLong* &comp_ret)
561   { throw GDLException("Struct expression not allowed in this context.");}
Where(DLong64 * & ret,SizeT & passed_count,bool comp,DLong64 * & comp_ret)562   void Where(DLong64* &ret, SizeT &passed_count, bool comp, DLong64* &comp_ret)
563   { throw GDLException("Struct expression not allowed in this context.");}
LogNeg()564   Data_<SpDByte>* LogNeg()
565   { throw GDLException("Struct expression not allowed in this context.");}
566   int  Sgn(); // -1,0,1
567   bool Equal( BaseGDL*) const;
568   bool EqualNoDelete( const BaseGDL*) const;
569   bool ArrayEqual( BaseGDL*);
570   bool ArrayNeverEqual( BaseGDL*);
571   // 'for' statement compliance (int types , float types scalar only)
572   bool ForCheck( BaseGDL**, BaseGDL** =NULL);
573   bool ForCondUp( BaseGDL*);
574   bool ForCondDown( BaseGDL*);
575   void ForAdd();
576   void ForAdd( BaseGDL* add=NULL);
577 
578   BaseGDL* UMinus(); // UMinus for SpDString returns float
579   DStructGDL*   NotOp();
580   DStructGDL*   AndOp( BaseGDL* r);
581   DStructGDL*   AndOpInv( BaseGDL* r);
582   DStructGDL*   OrOp( BaseGDL* r);
583   DStructGDL*   OrOpInv( BaseGDL* r);
584   DStructGDL*   XorOp( BaseGDL* r);
585   DStructGDL*   Add( BaseGDL* r);
586   DStructGDL*   AddInv( BaseGDL* r);
587   DStructGDL*   Sub( BaseGDL* r);
588   DStructGDL*   SubInv( BaseGDL* r);
589   DStructGDL*   GtMark( BaseGDL* r);
590   DStructGDL*   LtMark( BaseGDL* r);
591   DStructGDL*   Mult( BaseGDL* r);
592   DStructGDL*   Div( BaseGDL* r);
593   DStructGDL*   DivInv( BaseGDL* r);
594   DStructGDL*   Mod( BaseGDL* r);
595   DStructGDL*   ModInv( BaseGDL* r);
596   DStructGDL*   Pow( BaseGDL* r);
597   DStructGDL*   PowInv( BaseGDL* r);
598   DStructGDL*   PowInt( BaseGDL* r);
599   DStructGDL*   MatrixOp( BaseGDL* r, bool atranspose, bool btranspose);
600 
601 
602   DStructGDL*   AndOpS( BaseGDL* r);
603   DStructGDL*   AndOpInvS( BaseGDL* r);
604   DStructGDL*   OrOpS( BaseGDL* r);
605   DStructGDL*   OrOpInvS( BaseGDL* r);
606   DStructGDL*   XorOpS( BaseGDL* r);
607   DStructGDL*   AddS( BaseGDL* r);
608   DStructGDL*   AddInvS( BaseGDL* r);
609   DStructGDL*   SubS( BaseGDL* r);
610   DStructGDL*   SubInvS( BaseGDL* r);
611   DStructGDL*   GtMarkS( BaseGDL* r);
612   DStructGDL*   LtMarkS( BaseGDL* r);
613   DStructGDL*   MultS( BaseGDL* r);
614   DStructGDL*   DivS( BaseGDL* r);
615   DStructGDL*   DivInvS( BaseGDL* r);
616   DStructGDL*   ModS( BaseGDL* r);
617   DStructGDL*   ModInvS( BaseGDL* r);
618   DStructGDL*   PowS( BaseGDL* r);
619   DStructGDL*   PowInvS( BaseGDL* r);
620 
621 
622   // operators returning a new value
623   DStructGDL* AndOpNew( BaseGDL* r);
624   DStructGDL* AndOpInvNew( BaseGDL* r);
625   DStructGDL* OrOpNew( BaseGDL* r);
626   DStructGDL* OrOpInvNew( BaseGDL* r);
627   DStructGDL* XorOpNew( BaseGDL* r);
628 //   DStructGDL* EqOpNew( BaseGDL* r);
629 //   DStructGDL* NeOpNew( BaseGDL* r);
630 //   DStructGDL* LeOpNew( BaseGDL* r);
631 //   DStructGDL* GeOpNew( BaseGDL* r);
632 //   DStructGDL* LtOpNew( BaseGDL* r);
633 //   DStructGDL* GtOpNew( BaseGDL* r);
634   DStructGDL* AddNew( BaseGDL* r);      // implemented
635   DStructGDL* AddInvNew( BaseGDL* r);      // implemented
636   DStructGDL* SubNew( BaseGDL* r);
637   DStructGDL* SubInvNew( BaseGDL* r);
638   DStructGDL* LtMarkNew( BaseGDL* r);
639   DStructGDL* GtMarkNew( BaseGDL* r);
640   DStructGDL* MultNew( BaseGDL* r);   // implemented
641   DStructGDL* DivNew( BaseGDL* r);
642   DStructGDL* DivInvNew( BaseGDL* r);
643   DStructGDL* ModNew( BaseGDL* r);
644   DStructGDL* ModInvNew( BaseGDL* r);
645   DStructGDL* PowNew( BaseGDL* r);
646   DStructGDL* PowInvNew( BaseGDL* r);
647   DStructGDL* PowIntNew( BaseGDL* r);   // implemented
648 
649   // operators with scalar returning a new value
650   DStructGDL* AndOpSNew( BaseGDL* r);
651   DStructGDL* AndOpInvSNew( BaseGDL* r);
652   DStructGDL* OrOpSNew( BaseGDL* r);
653   DStructGDL* OrOpInvSNew( BaseGDL* r);
654   DStructGDL* XorOpSNew( BaseGDL* r);
655   DStructGDL* AddSNew( BaseGDL* r);         // implemented
656   DStructGDL* AddInvSNew( BaseGDL* r);    // implemented
657   DStructGDL* SubSNew( BaseGDL* r);
658   DStructGDL* SubInvSNew( BaseGDL* r);
659   DStructGDL* LtMarkSNew( BaseGDL* r);
660   DStructGDL* GtMarkSNew( BaseGDL* r);
661   DStructGDL* MultSNew( BaseGDL* r);      // implemented
662   DStructGDL* DivSNew( BaseGDL* r);
663   DStructGDL* DivInvSNew( BaseGDL* r);
664   DStructGDL* ModSNew( BaseGDL* r);
665   DStructGDL* ModInvSNew( BaseGDL* r);
666   DStructGDL* PowSNew( BaseGDL* r);
667   DStructGDL* PowInvSNew( BaseGDL* r);
668 
669 
670 
671   BaseGDL* EqOp( BaseGDL* r);
672   BaseGDL* NeOp( BaseGDL* r);
673   BaseGDL* GtOp( BaseGDL* r);
674   BaseGDL* GeOp( BaseGDL* r);
675   BaseGDL* LtOp( BaseGDL* r);
676   BaseGDL* LeOp( BaseGDL* r);
677 
678   // assigns srcIn to this at ixList, if ixList is NULL does linear copy
679   // assumes: ixList has this already set as variable
680   // frees overwritten members
681   void AssignAt( BaseGDL* srcIn, ArrayIndexListT* ixList, SizeT offset);
682   void AssignAt( BaseGDL* srcIn, ArrayIndexListT* ixList);
683   void AssignAt( BaseGDL* srcIn);
684   void AssignAtIx( RangeT ixR, BaseGDL* srcIn);
685 
DecAt(ArrayIndexListT * ixList)686   void DecAt( ArrayIndexListT* ixList)
687   {
688     throw GDLException("Struct expression not allowed in this context.");
689   }
IncAt(ArrayIndexListT * ixList)690   void IncAt( ArrayIndexListT* ixList)
691   {
692     throw GDLException("Struct expression not allowed in this context.");
693   }
Dec()694   void Dec()
695   {
696     throw GDLException("Struct expression not allowed in this context.");
697   }
Inc()698   void Inc()
699   {
700     throw GDLException("Struct expression not allowed in this context.");
701   }
702 
703   // used by AccessDescT for resolving, no checking is done
704   // inserts srcIn[ ixList] at offset
705   // here d is initially empty -> no deleting of old data in InsertAt
706   void InsertAt( SizeT offset, BaseGDL* srcIn, ArrayIndexListT* ixList);
707 
708   // returns (*this)[ ixList]
709   DStructGDL* Index( ArrayIndexListT* ixList);
710   DStructGDL* NewIx( SizeT ix);
711 
712   // formatting output functions
713 
714   SizeT OFmtA( std::ostream* os, SizeT offset, SizeT num, int width, int code);
715   SizeT OFmtF( std::ostream* os, SizeT offs, SizeT num, int width, int prec, const int code=0, const BaseGDL::IOMode oM = FIXED);
716   SizeT OFmtI( std::ostream* os, SizeT offs, SizeT num, int width, int minN, int code=0, BaseGDL::IOMode oM = DEC);
717 
718   SizeT IFmtA( std::istream* is, SizeT offset, SizeT num, int width);
719   SizeT IFmtF( std::istream* is, SizeT offs, SizeT num, int width);
720   SizeT IFmtI( std::istream* is, SizeT offs, SizeT num, int width,
721 		BaseGDL::IOMode oM = DEC);
722   SizeT IFmtCal( std::istream* is, SizeT offs, SizeT r, int width, BaseGDL::Cal_IOMode cMode);
723 private:
724   void IFmtAll( SizeT offs, SizeT r,
725 		SizeT& firstOut, SizeT& firstOffs, SizeT& tCount, SizeT& tCountOut);
726 
727   void OFmtAll( SizeT offs, SizeT r,
728 		SizeT& firstOut, SizeT& firstOffs, SizeT& tCount, SizeT& tCountOut);
729   SizeT OFmtCal( std::ostream* os, SizeT offs, SizeT r, int w, int d, char *f,  int code, BaseGDL::Cal_IOMode oMode);
730   // inserts srcIn at ixDim
731   // respects the exact structure
732   // used by Assign -> old data must be freed
733   void InsAt( DStructGDL* srcIn, ArrayIndexListT* ixList);
734 
735   // used for concatenation, called from CatArray
736   // assumes that everything is checked (see CatInfo)
737   void CatInsert( const DStructGDL* srcArr, const SizeT atDim, SizeT& at);
738 };
739 
740 #endif
741