1 /*************************************************************************** 2 datatypes.hpp - defines all data types of GDL except DStructGDL 3 ------------------- 4 begin : Tue Feb 13 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 19 #ifndef DATATYPES_HPP_ 20 #define DATATYPES_HPP_ 21 22 23 #include "typedefs.hpp" 24 #include "basegdl.hpp" 25 #include "typetraits.hpp" 26 27 #include <string> 28 29 #if defined(__GNUC__) && !defined(__INTEL_COMPILER) 30 // by default intel C++ defines __GNUC__ 31 #pragma interface 32 #endif 33 34 35 // for each group we need one definition 36 // usage: GDL_DEFINE_INTEGER_FUNCTION(retType) fName( arg list) { definition} 37 #define GDL_DEFINE_INTEGER_FUNCTION( retType ) template<typename Sp>template< typename U> typename U::template IfInteger< retType >::type Data_<Sp>:: 38 #define GDL_DEFINE_FLOAT_FUNCTION( retType ) template<typename Sp>template< typename U> typename U::template IfFloat< retType >::type Data_<Sp>:: 39 #define GDL_DEFINE_COMPLEX_FUNCTION( retType ) template<typename Sp>template< typename U> typename U::template IfComplex< retType >::type Data_<Sp>:: 40 #define GDL_DEFINE_OTHER_FUNCTION( retType ) template<typename Sp>template< typename U> typename U::template IfOther< retType >::type Data_<Sp>:: 41 42 const size_t multiAlloc = 256; 43 44 template<class Sp> 45 class Data_: public Sp 46 { 47 48 // save some typing. Declares function "fName" for all four groups (with return type "retType") 49 #define GDL_DECLARE_FUNCTION( retType, fName, ... ) \ 50 template< typename U = Sp > typename U::template IfInteger< retType >::type fName( __VA_ARGS__); \ 51 template< typename U = Sp > typename U::template IfFloat< retType >::type fName( __VA_ARGS__); \ 52 template< typename U = Sp > typename U::template IfComplex< retType >::type fName( __VA_ARGS__); \ 53 template< typename U = Sp > typename U::template IfOther< retType >::type fName( __VA_ARGS__) 54 55 56 public: 57 typedef typename Sp::Ty Ty; 58 typedef Sp Traits; 59 60 #ifdef _MSC_VER 61 public: // MSC cannot handle friend template specialization properly 62 #else 63 private: 64 #endif 65 66 typedef typename Sp::DataT DataT; 67 #ifdef USE_EIGEN 68 EIGEN_ALIGN16 DataT dd; // the data 69 #else 70 DataT dd; // the data 71 #endif 72 73 public: 74 75 // #define TESTTG // TEST TEMPLATE GROUPING 76 77 #ifdef TESTTG 78 79 void TestTemplateGrouping(); 80 81 // #define GDL_TEMPLATE_Integer( retType ) template< typename U = Sp > typename U::template IfInteger< retType >::type 82 // #define GDL_TEMPLATE_IntegerDef( retType ) template<typename Sp>template< typename U> typename U::template IfInteger< retType >::type Data_<Sp>:: 83 84 85 GDL_DECLARE_FUNCTION(bool,Test2); 86 87 // template< typename U = Sp > 88 //typename U::template IfInteger<bool>::type 89 // GDL_TEMPLATE_Integer(bool) Test2(); 90 // template< typename U = Sp > 91 // typename U::template IfFloat<bool>::type 92 // Test2(); 93 // template< typename U = Sp > 94 // typename U::template IfComplex<bool>::type 95 // Test2(); 96 // template< typename U = Sp > 97 // typename U::template IfOther<bool>::type 98 // Test2(); 99 100 #endif 101 102 public: 103 // memory management optimization 104 static FreeListT freeList; 105 106 // operator new and delete 107 static void* operator new( size_t bytes); 108 static void operator delete( void *ptr); 109 110 //structors 111 ~Data_(); 112 113 // default 114 Data_(); 115 116 // scalar 117 Data_(const Ty& d_); 118 119 // new array, no zero or indgen 120 Data_(const dimension& dim_, BaseGDL::InitType iT, 121 DDouble start = 0, DDouble increment = 1); 122 123 // new array, zero fields 124 Data_(const dimension& dim_); 125 126 // new array from Ty[], one dimensional 127 Data_( const Ty* p, SizeT nEl); 128 129 // new array from DataT Data_(const dimension & dim_,const DataT & dd_)130 Data_(const dimension& dim_, const DataT& dd_): 131 Sp( dim_), dd( dd_) {} 132 133 // c-i 134 Data_(const Data_& d_);//: Sp(d_.dim), dd(d_.dd) {} 135 136 // operators 137 // assignment. 138 Data_& operator=(const BaseGDL& right); 139 140 // for structs 141 void InitFrom(const BaseGDL& right); 142 143 // one dim array access (unchecked) operator [](const SizeT d1)144 inline Ty& operator[] (const SizeT d1) { return dd[d1];} operator [](const SizeT d1) const145 inline const Ty& operator[] (const SizeT d1) const { return dd[d1];} 146 // Ty& operator[] (const SizeT d1) { return dd[d1];} 147 148 template<class Sp2> 149 friend std::istream& operator>>(std::istream& i, Data_<Sp2>& data_); 150 151 // valarrays cannot be resized (without loosing data) 152 // inline DataT& Resize( SizeT n); 153 154 // // note that min and max these are not defined in BaseGDL 155 // Ty min() const;// { return dd.min();} 156 // Ty max() const;// { return dd.max();} 157 158 bool Greater(SizeT i1, SizeT i2) const; // comp 2 elements 159 bool Equal(SizeT i1, SizeT i2) const; // comp 2 elements 160 161 BaseGDL* CShift( DLong d) const; 162 BaseGDL* CShift( DLong d[MAXRANK]) const; 163 164 BaseGDL* Transpose( DUInt* perm); 165 BaseGDL* Rotate( DLong dir); 166 void Reverse( DLong dim); 167 BaseGDL* DupReverse( DLong dim); 168 169 // for use by MIN and MAX functions 170 void MinMax( DLong* minE, DLong* maxE, BaseGDL** minVal, BaseGDL** maxVal, 171 bool omitNaN, 172 SizeT start = 0, SizeT stop = 0, SizeT step = 1, DLong valIx = -1, bool useAbs = false); 173 174 bool EqType( const BaseGDL* r) const; 175 176 void* DataAddr();// SizeT elem=0); 177 178 Ty Sum() const; 179 180 SizeT N_Elements() const; 181 SizeT Size() const; 182 SizeT NBytes() const; 183 SizeT ToTransfer() const; // IO transfer count 184 SizeT Sizeof() const; 185 186 int HashCompare( BaseGDL* p2) const; 187 188 void Clear(); 189 void Construct(); // construction (for DStructGDL) 190 void ConstructTo0(); // construction (for DStructGDL) 191 void Destruct(); // destruction (for DStructGDL) 192 193 BaseGDL* SetBuffer( const void* b); 194 void SetBufferSize( SizeT s); 195 196 BaseGDL* AssocVar( int, SizeT); 197 198 std::ostream& ToStream(std::ostream& o, SizeT width = 0, 199 SizeT* actPosPtr = NULL); 200 std::istream& FromStream(std::istream& i); 201 202 // used by the interpreter 203 int Scalar2Index( SizeT& st) const; 204 int Scalar2RangeT( RangeT& st) const; 205 RangeT LoopIndex() const; 206 DDouble HashValue() const; 207 208 // used for indexing of arrays 209 SizeT GetAsIndex( SizeT i) const; 210 SizeT GetAsIndexStrict( SizeT i) const; 211 212 // make a duplicate on the heap 213 Data_* Dup() const; 214 // // make a duplicate at loc 215 // Data_* Dup( void* loc) const { return ::new ( loc) Data_(*this);} 216 217 // bool OutOfRangeOfInt() const; 218 Scalar() const219 bool Scalar() const { return (dd.size() == 1);} StrictScalar() const220 bool StrictScalar() const { return (this->Rank() == 0);} 221 Scalar(Ty & s) const222 bool Scalar(Ty& s) const { 223 if( dd.size() != 1) return false; 224 s=dd[0]; 225 return true; } StrictScalar(Ty & s) const226 bool StrictScalar(Ty& s) const { 227 if( this->Rank() != 0) return false; 228 s=dd[0]; 229 return true; } 230 231 Data_* New( const dimension& dim_, BaseGDL::InitType noZero=BaseGDL::ZERO) const; 232 Data_* NewResult() const; 233 234 // convert *this to other 'destTy' 235 BaseGDL* Convert2( DType destTy, 236 BaseGDL::Convert2Mode=BaseGDL::CONVERT); 237 238 // not all compilers can handle template friend member functions 239 #ifndef _MSC_VER 240 # if __GNUC__ >= 4 241 # if defined(__clang__) 242 // suppress: warning: dependent nested name specifier 'Data_<Sp2>::' for friend class declaration is not supported; turning off access control for 'Data_' [-Wunsupported-friend] 243 # pragma clang diagnostic push 244 # pragma clang diagnostic ignored "-Wunsupported-friend" 245 // make all other Convert2 functions friends 246 template<class Sp2> 247 friend BaseGDL* Data_<Sp2>::Convert2( DType destTy, 248 BaseGDL::Convert2Mode); 249 # pragma clang diagnostic pop 250 # endif 251 # else 252 // this explicit version does not work with GCC 4.0 253 friend BaseGDL* Data_<SpDByte>::Convert2( DType destTy, BaseGDL::Convert2Mode); 254 friend BaseGDL* Data_<SpDInt>::Convert2( DType destTy, BaseGDL::Convert2Mode); 255 friend BaseGDL* Data_<SpDUInt>::Convert2( DType destTy, BaseGDL::Convert2Mode); 256 friend BaseGDL* Data_<SpDLong>::Convert2( DType destTy, BaseGDL::Convert2Mode); 257 friend BaseGDL* Data_<SpDULong>::Convert2( DType destTy, BaseGDL::Convert2Mode); 258 friend BaseGDL* Data_<SpDLong64>::Convert2( DType destTy, BaseGDL::Convert2Mode); 259 friend BaseGDL* Data_<SpDULong64>::Convert2( DType destTy, BaseGDL::Convert2Mode); 260 friend BaseGDL* Data_<SpDFloat>::Convert2( DType destTy, BaseGDL::Convert2Mode); 261 friend BaseGDL* Data_<SpDDouble>::Convert2( DType destTy, BaseGDL::Convert2Mode); 262 friend BaseGDL* Data_<SpDString>::Convert2( DType destTy, BaseGDL::Convert2Mode); 263 friend BaseGDL* Data_<SpDPtr>::Convert2( DType destTy, BaseGDL::Convert2Mode); 264 friend BaseGDL* Data_<SpDObj>::Convert2( DType destTy, BaseGDL::Convert2Mode); 265 friend BaseGDL* Data_<SpDComplex>::Convert2( DType destTy, BaseGDL::Convert2Mode); 266 friend BaseGDL* Data_<SpDComplexDbl>::Convert2( DType destTy, BaseGDL::Convert2Mode); 267 268 # endif 269 #endif 270 271 bool True(); 272 bool False(); 273 bool LogTrue(); 274 bool LogTrue( SizeT ix); 275 void Where(DLong* &ret, SizeT &passed_count, bool comp, DLong* &comp_ret); 276 void Where(DLong64* &ret, SizeT &passed_count, bool comp, DLong64* &comp_ret); 277 Data_<SpDByte>* LogNeg(); 278 int Sgn(); // returns -1,0,1 279 bool Equal( BaseGDL*) const; 280 bool EqualNoDelete( const BaseGDL*) const; 281 bool ArrayEqual( BaseGDL*); 282 bool ArrayNeverEqual( BaseGDL*); 283 bool ForCheck( BaseGDL**, BaseGDL** =NULL); 284 bool ForCondUp( BaseGDL*); 285 bool ForCondDown( BaseGDL*); 286 bool ForAddCondUp( BaseGDL* loopInfo); 287 // bool ForAddCondUp( ForLoopInfoT& loopInfo); 288 // bool ForCondUpDown( BaseGDL*); 289 void ForAdd(); 290 void ForAdd( BaseGDL* add); 291 292 BaseGDL* Abs() const; 293 294 BaseGDL* Convol( BaseGDL* kIn, BaseGDL* scaleIn, BaseGDL* bias, 295 bool center, bool normalize, int edgeMode, 296 bool doNan, BaseGDL* missing, bool doMissing, 297 BaseGDL* invalid, bool doInvalid); 298 BaseGDL* Smooth(DLong* width, int edgeMode, 299 bool doNan, BaseGDL* missing); 300 BaseGDL* Rebin( const dimension& newDim, bool sample); 301 302 void Assign( BaseGDL* src, SizeT nEl); 303 304 template< typename To> typename Data_<To>::Ty GetAs( SizeT i); 305 // { 306 // return dd[ i]; 307 // } 308 309 BaseGDL* Log(); 310 BaseGDL* LogThis(); 311 312 BaseGDL* Log10(); 313 BaseGDL* Log10This(); 314 315 // operators 316 BaseGDL* UMinus(); // UMinus for SpDString returns float 317 Data_* NotOp(); 318 // GDL_DECLARE_FUNCTION( Data_*, AndOp, BaseGDL* r); 319 Data_* AndOp( BaseGDL* r); 320 Data_* AndOpInv( BaseGDL* r); 321 Data_* OrOp( BaseGDL* r); 322 Data_* OrOpInv( BaseGDL* r); 323 Data_* XorOp( BaseGDL* r); 324 325 BaseGDL* Add( BaseGDL* r); 326 BaseGDL* AddInv( BaseGDL* r); 327 BaseGDL* AddS( BaseGDL* r); 328 BaseGDL* AddInvS( BaseGDL* r); 329 330 BaseGDL* AddNew( BaseGDL* r); // implemented 331 BaseGDL* AddInvNew( BaseGDL* r); // implemented 332 BaseGDL* AddSNew( BaseGDL* r); // implemented 333 BaseGDL* AddInvSNew( BaseGDL* r); // implemented 334 335 // Data_* AddNew( BaseGDL* r); 336 // Data_* AddInvNew( BaseGDL* r); 337 BaseGDL* Sub( BaseGDL* r); 338 BaseGDL* SubInv( BaseGDL* r); 339 Data_* GtMark( BaseGDL* r); 340 Data_* LtMark( BaseGDL* r); 341 Data_* Mult( BaseGDL* r); 342 // Data_* MultNew( BaseGDL* r); 343 Data_* Div( BaseGDL* r); 344 Data_* DivInv( BaseGDL* r); 345 Data_* Mod( BaseGDL* r); 346 Data_* ModInv( BaseGDL* r); 347 Data_* Pow( BaseGDL* r); 348 Data_* PowInv( BaseGDL* r); 349 Data_* PowInt( BaseGDL* r); 350 // Data_* PowIntNew( BaseGDL* r); 351 352 Data_* MatrixOp( BaseGDL* r, bool atranspose, bool btranspose); 353 354 // operators with scalar 355 Data_* AndOpS( BaseGDL* r); 356 Data_* AndOpInvS( BaseGDL* r); 357 Data_* OrOpS( BaseGDL* r); 358 Data_* OrOpInvS( BaseGDL* r); 359 Data_* XorOpS( BaseGDL* r); 360 // Data_* AddSNew( BaseGDL* r); 361 // Data_* AddInvSNew( BaseGDL* r); 362 Data_* SubS( BaseGDL* r); 363 Data_* SubInvS( BaseGDL* r); 364 Data_* GtMarkS( BaseGDL* r); 365 Data_* LtMarkS( BaseGDL* r); 366 Data_* MultS( BaseGDL* r); 367 // Data_* MultSNew( BaseGDL* r); 368 Data_* DivS( BaseGDL* r); 369 Data_* DivInvS( BaseGDL* r); 370 Data_* ModS( BaseGDL* r); 371 Data_* ModInvS( BaseGDL* r); 372 Data_* PowS( BaseGDL* r); 373 Data_* PowInvS( BaseGDL* r); 374 375 // operators returning a new value 376 Data_* AndOpNew( BaseGDL* r); 377 Data_* AndOpInvNew( BaseGDL* r); 378 Data_* OrOpNew( BaseGDL* r); 379 Data_* OrOpInvNew( BaseGDL* r); 380 Data_* XorOpNew( BaseGDL* r); 381 // Data_* EqOpNew( BaseGDL* r); 382 // Data_* NeOpNew( BaseGDL* r); 383 // Data_* LeOpNew( BaseGDL* r); 384 // Data_* GeOpNew( BaseGDL* r); 385 // Data_* LtOpNew( BaseGDL* r); 386 // Data_* GtOpNew( BaseGDL* r); 387 BaseGDL* SubNew( BaseGDL* r); 388 BaseGDL* SubInvNew( BaseGDL* r); 389 Data_* LtMarkNew( BaseGDL* r); 390 Data_* GtMarkNew( BaseGDL* r); 391 Data_* MultNew( BaseGDL* r); // implemented 392 Data_* DivNew( BaseGDL* r); 393 Data_* DivInvNew( BaseGDL* r); 394 Data_* ModNew( BaseGDL* r); 395 Data_* ModInvNew( BaseGDL* r); 396 Data_* PowNew( BaseGDL* r); 397 Data_* PowInvNew( BaseGDL* r); 398 Data_* PowIntNew( BaseGDL* r); // implemented 399 400 // operators with scalar returning a new value 401 Data_* AndOpSNew( BaseGDL* r); 402 Data_* AndOpInvSNew( BaseGDL* r); 403 Data_* OrOpSNew( BaseGDL* r); 404 Data_* OrOpInvSNew( BaseGDL* r); 405 Data_* XorOpSNew( BaseGDL* r); 406 BaseGDL* SubSNew( BaseGDL* r); 407 BaseGDL* SubInvSNew( BaseGDL* r); 408 Data_* LtMarkSNew( BaseGDL* r); 409 Data_* GtMarkSNew( BaseGDL* r); 410 Data_* MultSNew( BaseGDL* r); // implemented 411 Data_* DivSNew( BaseGDL* r); 412 Data_* DivInvSNew( BaseGDL* r); 413 Data_* ModSNew( BaseGDL* r); 414 Data_* ModInvSNew( BaseGDL* r); 415 Data_* PowSNew( BaseGDL* r); 416 Data_* PowInvSNew( BaseGDL* r); 417 418 419 BaseGDL* EqOp( BaseGDL* r); 420 BaseGDL* NeOp( BaseGDL* r); 421 BaseGDL* GtOp( BaseGDL* r); 422 BaseGDL* GeOp( BaseGDL* r); 423 BaseGDL* LtOp( BaseGDL* r); 424 BaseGDL* LeOp( BaseGDL* r); 425 426 // used by interpreter, calls CatInsert 427 Data_* CatArray( ExprListT& exprList, const SizeT catRank, 428 const SizeT rank); 429 // used for concatenation, called from CatArray 430 // assumes that everything is checked (see CatInfo) 431 void CatInsert( const Data_* srcArr, const SizeT atDim, SizeT& at); 432 433 // assigns srcIn to this at ixList, if ixList is NULL does linear copy 434 // assumes: ixList has this already set as variable 435 void AssignAt( BaseGDL* srcIn, ArrayIndexListT* ixList, SizeT offset); 436 void AssignAt( BaseGDL* srcIn, ArrayIndexListT* ixList); 437 void AssignAt( BaseGDL* srcIn); 438 439 void AssignAtIx( RangeT ix, BaseGDL* srcIn); 440 441 // decrement (--) and increment (++) operators 442 void DecAt( ArrayIndexListT* ixList); 443 void IncAt( ArrayIndexListT* ixList); 444 void Dec(); 445 void Inc(); 446 447 // used by AccessDescT for resolving, no checking is done 448 // inserts srcIn[ ixList] at offset 449 void InsertAt( SizeT offset, BaseGDL* srcIn, ArrayIndexListT* ixList); 450 451 // returns (*this)[ ixList] 452 Data_* Index( ArrayIndexListT* ixList); 453 454 // return a new type of itself 455 BaseGDL* NewIx( SizeT ix); 456 Data_* NewIx( BaseGDL* ix, bool strict); 457 Data_* NewIx( AllIxBaseT* ix, const dimension* dIn); 458 Data_* NewIxFrom( SizeT s); 459 Data_* NewIxFrom( SizeT s, SizeT e); 460 Data_* NewIxFromStride( SizeT s, SizeT stride); 461 Data_* NewIxFromStride( SizeT s, SizeT e, SizeT stride); 462 463 // binary input/output 464 std::ostream& Write( std::ostream& os, bool swapEndian, bool compress, 465 XDR *xdrs); 466 std::istream& Read( std::istream& os, bool swapEndian, bool compress, 467 XDR *xdrs); 468 469 SizeT OFmtA( std::ostream* os, SizeT offset, SizeT num, int width, const int code=0); 470 SizeT OFmtF( std::ostream* os, SizeT offs, SizeT num, int width, int prec, const int code=0, const BaseGDL::IOMode oM = BaseGDL::FIXED); 471 SizeT OFmtI( std::ostream* os, SizeT offs, SizeT num, int width, int minN, int code=0, BaseGDL::IOMode oM = BaseGDL::DEC); 472 SizeT OFmtCal( std::ostream* os, SizeT offs, SizeT num, int width, int minN, char *f, int code=0, BaseGDL::Cal_IOMode oM = BaseGDL::DEFAULT); 473 // formatting input functions 474 SizeT IFmtA( std::istream* is, SizeT offset, SizeT num, int width); 475 SizeT IFmtF( std::istream* is, SizeT offs, SizeT num, int width); 476 SizeT IFmtI( std::istream* is, SizeT offs, SizeT num, int width, 477 BaseGDL::IOMode oM = BaseGDL::DEC); 478 SizeT IFmtCal( std::istream* is, SizeT offs, SizeT r, int width, BaseGDL::Cal_IOMode cMode); 479 #ifdef USE_PYTHON 480 public: 481 PyObject* ToPython(); 482 private: 483 PyObject* ToPythonScalar(); 484 #endif 485 486 private: 487 488 // inserts srcIn at ixDim, used by AssignAt(...) 489 // respects the exact structure 490 void InsAt( Data_* srcIn, ArrayIndexListT* ixList, SizeT offset = 0); 491 492 // only to be used here 493 #undef GDL_DECLARE_FUNCTION 494 495 }; 496 497 // template<> Data_<SpDPtr>::Data_(const Ty& d_); 498 // template<> Data_<SpDObj>::Data_(const Ty& d_); 499 500 #include "specializations.hpp" 501 502 typedef Data_<SpDByte> DByteGDL; 503 typedef Data_<SpDInt> DIntGDL; 504 typedef Data_<SpDUInt> DUIntGDL; 505 typedef Data_<SpDLong> DLongGDL; 506 typedef Data_<SpDULong> DULongGDL; 507 typedef Data_<SpDLong64> DLong64GDL; 508 typedef Data_<SpDULong64> DULong64GDL; 509 typedef Data_<SpDFloat> DFloatGDL; 510 typedef Data_<SpDDouble> DDoubleGDL; 511 typedef Data_<SpDString> DStringGDL; 512 typedef Data_<SpDPtr> DPtrGDL; 513 typedef Data_<SpDObj> DObjGDL; 514 typedef Data_<SpDComplex> DComplexGDL; 515 typedef Data_<SpDComplexDbl> DComplexDblGDL; 516 517 // DStructGDL defined separately 518 519 // on OS X isfinite is not defined 520 #if defined(__APPLE__) && defined(OLD_DARWIN) && !defined(isfinite) 521 522 #ifdef __cplusplus 523 extern "C" { 524 #endif 525 #define isfinite( x ) ( ( sizeof ( x ) == sizeof(double) ) ? \ 526 __isfinited ( x ) : \ 527 ( sizeof ( x ) == sizeof( float) ) ? \ 528 __isfinitef ( x ) : \ 529 __isfinite ( x ) ) 530 #ifdef __cplusplus 531 } 532 #endif 533 #endif 534 535 // isfinite & isinf for Solaris 536 #if defined(__sun__) 537 # include <ieeefp.h> 538 # define isfinite finite 539 # ifndef isinf 540 # define isinf(x) (!finite(x) && x==x) 541 # endif 542 #endif 543 544 #endif 545