1 /***************************************************************************
2 typedefs.hpp - basic typedefs
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 TYPEDEFS_HPP_
19 #define TYPEDEFS_HPP_
20
21 // check for needed libraries here as this file is included by most sources
22 // (via dimension.hpp via basegdl.hpp)
23 #ifdef HAVE_CONFIG_H
24
25 #include <config.h>
26
27 #ifndef HAVE_LIBGSL
28 #error "GNU Scientific Library not installed. Please see README file."
29 #endif
30
31 #ifndef HAVE_LIBGSLCBLAS
32 #error "CBLAS (part of GNU Scientific Library) not installed. Please see README file."
33 #endif
34
35 #ifndef HAVE_LIBPLPLOTCXXD
36 #error "plplot not installed. Please see README file."
37 #endif
38
39 #endif // HAVE_CONFIG_H
40
41 // Python.h must be included before everything else
42 #if defined(USE_PYTHON) || defined(PYTHON_MODULE)
43 #undef _POSIX_C_SOURCE // get rid of warning
44 #undef _XOPEN_SOURCE // get rid of warning
45 #undef HAVE_PROTOTYPES // get rid of warning
46
47 //libreadline must be deactivated after Python.h if we do not use libreadline
48 #ifndef HAVE_LIBREADLINE
49 #define GDL_NOT_HAVE_READLINE
50 #endif
51
52 #include <Python.h>
53
54 #ifdef GDL_NOT_HAVE_READLINE
55 #undef HAVE_LIBREADLINE
56 #endif
57 #undef GDL_NOT_HAVE_READLINE
58
59 //#ifndef _POSIX_C_SOURCE
60 //#warning "_POSIX_C_SOURCE not defined in Python.h (remove #undef)"
61 //#endif
62 //#ifndef _XOPEN_SOURCE
63 //#warning "_XOPEN_SOURCE not defined in Python.h (remove #undef)"
64 //#endif
65 //#ifndef HAVE_PROTOTYPES
66 //#warning "HAVE_PROTOTYPES not defined in Python.h (remove #undef)"
67 //#endif
68 #endif
69
70 #include <set>
71 #include <string>
72 // #include <string.h> // memcopy
73 #include <cstring> // memcopy
74 // #include <deque>
75 #include <complex>
76 #include <vector>
77 #include <valarray>
78 #include <cassert>
79 #include <iostream>
80
81 #undef USE_MPFR
82
83 #ifdef USE_MPFR
84 #include "mpreal.h"
85 #endif
86
87 // // undef for releases (should not give diagnostics)
88 // // define for the CVS (where the default sizes can easily be adjusted)
89 // #define GDL_CVS_VERSION
90 // //#undef GDL_CVS_VERSION
91 // // ?
92 // #ifdef GDL_CVS_VERSION
93 // #include <iostream>
94 // #endif
95
96 //#define TRACE_OMP_CALLS
97 #undef TRACE_OMP_CALLS
98
99 #if defined(_OPENMP) && defined(TRACE_OMP_CALLS)
100 #define TRACEOMP( file, line) std::cout << "TRACEOMP\t" << file << "\t" << line << std::endl;
101 #else
102 #define TRACEOMP( file, line)
103 #endif
104
105 // SA: fixing bug no. 3296360
106 typedef unsigned long long int SizeT;
107 typedef long long int RangeT;
108 typedef long long int OMPInt;
109
110 const SizeT MAXRANK=8; // arrays are limited to 8 dimensions
111 const std::string MAXRANK_STR("8"); // for use in strings (error messages)
112 const std::string INTERNAL_LIBRARY_STR("<INTERNAL_LIBRARY>");
113
114 //// SA: the version introduced by Joel in 2006:
115 ////#if defined(HAVE_64BIT_OS)
116 //// typedef unsigned long long int SizeT;
117 //// typedef long long int RangeT;
118 ////#else
119 //// typedef unsigned int SizeT;
120 //// typedef int RangeT;
121 ////#endif
122
123 // SA: the original version from 2005:
124 //typedef size_t SizeT;
125
126
127 typedef unsigned int UInt;
128 typedef unsigned long ULong;
129
130
131 // convenient naming
132 typedef unsigned char DByte;
133 // typedef int DInt;
134 // typedef unsigned int DUInt;
135 // typedef long int DLong;
136 // typedef unsigned long int DULong;
137
138 #ifdef _MSC_VER
139 typedef __int64 DLong64;
140 typedef unsigned __int64 DULong64;
141
142 #else
143 //typedef long int DLong64;
144 //typedef unsigned long int DULong64;
145 typedef long long int DLong64;
146 typedef unsigned long long int DULong64;
147 #endif
148
149 #ifdef USE_MPFR
150
151 typedef __int128 DLong128;
152 typedef unsigned __int128 DULong128;
153
154 typedef long double DLDouble;
155 typedef std::complex<DLDouble> DComplexLDbl;
156
157
158 typedef mpfr::mpreal DArbitrary;
159 #endif
160
161
162 typedef short DInt;
163 typedef unsigned short DUInt;
164 typedef int DLong;
165 typedef unsigned int DULong;
166 typedef float DFloat;
167 typedef double DDouble;
168 typedef std::string DString;
169 typedef SizeT DPtr; // ptr to heap
170 typedef DPtr DObj; // ptr to object heap
171 typedef std::complex<DFloat> DComplex;
172 typedef std::complex<DDouble> DComplexDbl;
173
174 // list of identifiers (used in several places)
175 typedef std::vector<std::string> IDList;
176 typedef std::vector<std::string> StrArr;
177
178 // for dpro
179 typedef std::vector<std::string> KeyVarListT;
180
181 // used by file.cpp and in other places
182 typedef std::vector<DString> FileListT;
183
184 //typedef std::valarray<SizeT> AllIxT;
185
186 typedef std::set< DPtr> DPtrListT;
187
188 //class ArrayIndexT;
189 //typedef std::vector<ArrayIndexT*> ArrayIndexVectorT;
190
191 // // for GUI (but also used in GDLEventHandler()
192 // typedef DLong WidgetIDT;
193
194 // to resolve include conflict (declared in gdlexception.hpp)
195 void ThrowGDLException( const std::string& str);
196
197 // for OpenMP (defined in objects.cpp - must be declared here)
198 extern DLong CpuHW_NCPU;
199 extern DLong CpuTPOOL_NTHREADS;
200 extern DLong64 CpuTPOOL_MIN_ELTS;
201 extern DLong64 CpuTPOOL_MAX_ELTS;
202
203 // convert something to string
204 template <typename T>
i2s(T i,SizeT w)205 inline std::string i2s( T i, SizeT w)// = 0)
206 {
207 std::ostringstream os;
208 os.width(w);
209 os << i;
210 return os.str();
211 }
212 template <typename T>
i2s(T i)213 inline std::string i2s( T i)
214 {
215 std::ostringstream os;
216 assert( os.width() == 0);
217 os << i;
218 return os.str();
219 }
220
221 // debug
222 //#include <iostream>
223
224 // searches IDList idL for std::string s, returns its position, -1 if not found
FindInIDList(IDList & idL,const std::string & s)225 inline int FindInIDList(IDList& idL,const std::string& s)
226 {
227 // int ix=0;
228 for(IDList::iterator i=idL.begin(); i != idL.end(); ++i)//, ++ix)
229 if( *i==s)
230 {
231 return i - idL.begin();
232 }
233
234 return -1;
235 }
236 // TODO: make a template
FindInKeyVarListT(KeyVarListT & idL,const std::string & s)237 inline int FindInKeyVarListT(KeyVarListT& idL,const std::string& s)
238 {
239 // int ix=0;
240 for(KeyVarListT::iterator i=idL.begin(); i != idL.end(); ++i)//, ++ix)
241 if( *i==s)
242 {
243 return i - idL.begin();
244 }
245
246 return -1;
247 }
248
249 // as auto_ptr is obsoleted Guard offers an alternative
250 template <class T>
251 class Guard
252 {
253 private:
254 T* guarded;
255
operator =(Guard & r)256 Guard& operator=( Guard& r)
257 {
258 if( &r == this) return *this;
259 delete guarded;
260 guarded = r.guarded;
261 r.guarded = NULL;
262 return *this;
263 }
264
265
266 public:
Guard()267 Guard(): guarded( NULL)
268 {}
Guard(T * c)269 Guard( T* c): guarded( c)
270 {}
271
Init(T * iniGuarded)272 void Init( T* iniGuarded) // saves a call to delete
273 {
274 assert( guarded == NULL);
275 guarded = iniGuarded;
276 }
Reset(T * newGuarded)277 void Reset( T* newGuarded)
278 {
279 delete guarded;
280 guarded = newGuarded;
281 }
282 // for compatibiltiy with replaced auto_ptr
reset(T * newGuarded)283 void reset( T* newGuarded)
284 {
285 delete guarded;
286 guarded = newGuarded;
287 }
Release()288 void Release()
289 {
290 guarded = NULL;
291 }
release()292 T* release()
293 {
294 T* g = guarded;
295 guarded = NULL;
296 return g;
297 }
Get() const298 T* Get() const
299 {
300 return guarded;
301 }
302 // for compatibiltiy with replaced auto_ptr
get() const303 T* get() const
304 {
305 return guarded;
306 }
307 // for compatibiltiy with replaced auto_ptr
operator ->() const308 T* operator->() const
309 {
310 return guarded;
311 }
IsNull() const312 bool IsNull() const
313 {
314 return guarded == NULL;
315 }
316
~Guard()317 ~Guard()
318 {
319 delete guarded;
320 }
321 };
322
323
324
325
326 // like auto_ptr but for arrays (delete[] is used upon destruction)
327 template <class T>
328 class ArrayGuard
329 {
330 private:
331 T* guarded;
332
333 public:
ArrayGuard()334 ArrayGuard(): guarded( NULL)
335 {}
ArrayGuard(T * c)336 ArrayGuard( T* c): guarded( c)
337 {}
338
Reset(T * newGuarded)339 void Reset( T* newGuarded)
340 {
341 delete[] guarded;
342 guarded = newGuarded;
343 }
Release()344 void Release()
345 {
346 guarded = NULL;
347 }
348
~ArrayGuard()349 ~ArrayGuard()
350 {
351 delete[] guarded;
352 }
353 };
354
355 // maintains size of stack, needed for exceptions
356 template <class T>
357 class StackGuard
358 {
359 private:
360 T& container;
361 typename T::size_type cSize;
362
363 public:
StackGuard(T & c)364 StackGuard( T& c): container( c)
365 {
366 cSize=container.size();
367 }
368
~StackGuard()369 ~StackGuard()
370 {
371 for( typename T::size_type s=container.size(); s > cSize; s--)
372 {
373 delete container.back();
374 container.pop_back();
375 }
376 }
377 };
378
379 // needed for exceptions
380 // does not delete elements
381 template <class T>
382 class StackSizeGuard
383 {
384 private:
385 T& container;
386 SizeT cSize;
387
388 public:
StackSizeGuard(T & c)389 StackSizeGuard( T& c): container( c)
390 {
391 cSize=container.size();
392 }
393
~StackSizeGuard()394 ~StackSizeGuard()
395 {
396 for( SizeT s=container.size(); s > cSize; s--)
397 { // no deleting here
398 container.pop_back();
399 }
400 }
401 };
402
403 // needed for exception savety (assures that after destruction the value
404 // will be the same as on instantiation)
405 template <class T>
406 class ValueGuard
407 {
408 private:
409 T& val;
410 T oldVal;
411
412 public:
ValueGuard(T & v)413 ValueGuard( T& v): val( v), oldVal( v)
414 {}
415
~ValueGuard()416 ~ValueGuard()
417 {
418 val = oldVal;
419 }
420 };
421
422 // like stackguard, but allows releasing
423 template <class T>
424 class PtrGuard
425 {
426 private:
427 T* container;
428 SizeT cSize;
429
430 public:
PtrGuard(T * c)431 PtrGuard( T* c): container( c)
432 {
433 cSize=container->size();
434 }
435
~PtrGuard()436 ~PtrGuard()
437 {
438 if( container != NULL)
439 for( SizeT s=container->size(); s > cSize; s--)
440 {
441 delete container->back();
442 container->pop_back();
443 }
444 }
445
Release()446 T* Release() { T* r=container; container=NULL; return r;}
447 };
448
449
450 // this data structure is optimized for list sizes < ExprListDefaultLength
451 // ExprListDefaultLength should be set such that it will probably never exceed
452 // note: it will work for larger lists as well, but then copy operations are performed
453 // The effect for indexed access was significant (>40%).
454 template< typename T, SizeT defaultLength> class PreAllocPListT
455 {
456 public:
457 typedef T* iterator;
458
459 private:
460 T* eArr;
461 T buf[defaultLength];
462 SizeT sz;
463 SizeT actLen;
464
465 public:
PreAllocPListT()466 PreAllocPListT(): eArr(buf), sz(0) {}
~PreAllocPListT()467 ~PreAllocPListT()
468 {
469 T* pEnd = &eArr[sz];
470 for( T* p = &eArr[0]; p!=pEnd;++p)
471 delete *p;
472 if( eArr != buf)
473 delete[] eArr;
474 }
push_back(T p)475 void push_back( T p)
476 {
477 if( sz < defaultLength)
478 {
479 eArr[ sz++] = p;
480 return;
481 }
482 if( sz == defaultLength)
483 actLen =defaultLength; // only init here
484 if( sz == actLen)
485 {
486 // /* #ifdef CVS_VERSION
487 // only for CVS version
488 // std::cerr << "PreAllocPListT: Resize triggered ("+i2s(sz)+"). All Ok! But please report at: https://github.com/gnudatalanguage/gdl/issues" << std::endl;
489 // #endif*/
490 actLen *= 2;
491 T* newArr = new T[ actLen];
492 for( SizeT i=0; i<sz; ++i)
493 newArr[i] = eArr[i];
494 if( eArr != buf)
495 delete[] eArr;
496 eArr = newArr;
497 }
498 eArr[ sz++] = p;
499 }
operator [](SizeT i) const500 T operator[]( SizeT i) const { assert( i<sz); return eArr[i];}
operator [](SizeT i)501 T& operator[]( SizeT i) { assert( i<sz); return eArr[i];}
size() const502 SizeT size() const { return sz;}
begin()503 iterator begin() { return &eArr[0];}
end()504 iterator end() { return &eArr[sz];}
505
empty() const506 bool empty() const { return sz == 0;}
front()507 T& front() { return eArr[0];}
front() const508 const T& front() const { return eArr[0];}
back()509 T& back() { return eArr[sz-1];}
back() const510 const T& back() const { return eArr[sz-1];}
511 };
512
513 class BaseGDL;
514 const int ExprListDefaultLength = 64;
515 typedef PreAllocPListT<BaseGDL*, ExprListDefaultLength> ExprListT;
516 typedef ExprListT::iterator ExprListIterT;
517
518 // exception save usage of GSL types
519 // you need to pass the gsl-object to guard and the gsl-clenaup (free) function
520 // example usage (for gsl_matrix):
521 //
522 // gsl_matrix *matrix = gsl_matrix_alloc(p0->Dim(0), p0->Dim(0));
523 //
524 // GDLGuard< gsl_matrix> gsl_matrix_guard( matrix, gsl_matrix_free);
525 // (of course no explicit call to the gsl-cleanup function must be done anymore)
526 template< typename GSLType, typename cleanupReturnType=void, typename cleanupArgType=GSLType>
527 class GDLGuard
528 {
529 GSLType* gslObject;
530
531 // note: cleanupArgType must be GSLType,
532 // except for free( void*) with GSLType==void*
533 // where it must be void
534 cleanupReturnType (*gslDestructor)(cleanupArgType*);
535
GDLGuard()536 GDLGuard() {}
537
538 public:
GDLGuard(void (* d)(GSLType *))539 GDLGuard( void (*d)(GSLType*)): gslObject( NULL), gslDestructor(d) {}
GDLGuard(GSLType * o,cleanupReturnType (* d)(cleanupArgType *))540 GDLGuard( GSLType* o, cleanupReturnType (*d)(cleanupArgType*)): gslObject( o), gslDestructor(d) {}
~GDLGuard()541 ~GDLGuard()
542 {
543 (*gslDestructor)( (cleanupArgType*)gslObject);
544 }
Init(GSLType * o)545 void Init( GSLType* o)
546 {
547 assert( gslObject == NULL);
548 gslObject = o;
549 }
550 };
551
552 // int fclose(...);
553 typedef GDLGuard< FILE, int> FILEGuard;
554
555 // class FILEGuard
556 // {
557 // FILE* fp;
558 //
559 // FILEGuard() {}
560 //
561 // public:
562 // FILEGuard( FILE* f): fp( f) {}
563 // ~FILEGuard()
564 // {
565 // fclose( fp);
566 // }
567 // };
568
569
570 class FreeListT
571 {
572 typedef void* PType;
573 PType* freeList;
574 SizeT sz;
575 SizeT endIx;
576
577 public:
FreeListT()578 FreeListT(): freeList(NULL), sz(0), endIx(0) {}
579
size() const580 SizeT size() const { return endIx;}
resize(SizeT s)581 void resize( SizeT s) { endIx = s;}
pop_back()582 PType pop_back() { assert(endIx > 0); return freeList[endIx--];}
583 // PType back() const { assert(endIx > 0); assert( freeList != NULL); return freeList[endIx];}
push_back(PType p)584 void push_back( PType p) { assert( endIx < (sz-1)); assert( freeList != NULL); freeList[++endIx] = p;}
585
Init(SizeT s,char * res,SizeT sizeOfType)586 char* Init( SizeT s, char* res, SizeT sizeOfType)
587 {
588 endIx = s;
589
590 //freeList[0] = res; // the ptr to free (not implemented)
591 for( size_t i=1; i<=endIx; ++i)
592 {
593 freeList[ i] = res;
594 res += sizeOfType;
595 }
596 return res;
597 }
598 // PType& operator[]( SizeT i)
599 // {
600 // return freeList[ i];
601 // }
602 // PType operator[]( SizeT i) const
603 // {
604 // return freeList[ i+1];
605 // }
606
reserve(SizeT s)607 void reserve( SizeT s)
608 {
609 assert( endIx == 0);
610
611 // alloc one more
612 if( ++s == sz)
613 return;
614
615 free( freeList);
616 freeList = (PType*) malloc( s * sizeof(PType));
617 if( freeList == NULL) // error
618 {
619 freeList = (PType*) malloc( sz * sizeof(PType));
620 if( freeList == NULL)
621 {
622 std::cerr << "% Error allocating free list. Probably already too late. Sorry.\n"
623 "Try to save what to save and immediately exit GDL session."<<std::endl;
624 }
625 else
626 {
627 std::cerr << "% Error allocating free list. Segmentation fault pending.\n"
628 "Try to save what to save and immediately exit GDL session."<<std::endl;
629 }
630 return;
631 }
632 sz = s;
633 }
634
635 };
636
637 //typedef std::vector< void*> FreeListT;
638
639 #endif
640