From 2189949b6c725f56ed07ba3417bb456bf18fca8c Mon Sep 17 00:00:00 2001 From: Orion Poplawski Date: Fri, 22 Mar 2013 12:18:47 -0600 Subject: [PATCH] - Update cvs patch to current cvs - Add patch to use python 2 with cmake --- gdl-cvs.patch | 23976 ++++++++++++++++++++++++++++++++++++++++++++- gdl-python.patch | 15 + gdl.spec | 11 +- 3 files changed, 23763 insertions(+), 239 deletions(-) create mode 100644 gdl-python.patch diff --git a/gdl-cvs.patch b/gdl-cvs.patch index c5d8a47..d23db42 100644 --- a/gdl-cvs.patch +++ b/gdl-cvs.patch @@ -2669,7 +2669,22 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/arrayindex.cpp gd } diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/arrayindex.hpp gdl/src/arrayindex.hpp --- gdl-0.9.3/src/arrayindex.hpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/arrayindex.hpp 2013-02-25 17:04:24.254182498 -0700 ++++ gdl/src/arrayindex.hpp 2013-03-21 14:04:04.003826906 -0600 +@@ -78,10 +78,10 @@ + virtual void Init( BaseGDL*, BaseGDL*, BaseGDL*) { assert( false);} + + virtual bool IsRange() { return false;} // default for non-ranges +- virtual BaseGDL* OverloadIndexNew() { assert( false);} +- virtual BaseGDL* OverloadIndexNew( BaseGDL*) { assert( false);} +- virtual BaseGDL* OverloadIndexNew( BaseGDL*, BaseGDL*) { assert( false);} +- virtual BaseGDL* OverloadIndexNew( BaseGDL*, BaseGDL*, BaseGDL*) { assert( false);} ++ virtual BaseGDL* OverloadIndexNew() { assert( false); return 0;} ++ virtual BaseGDL* OverloadIndexNew( BaseGDL*) { assert( false); return 0;} ++ virtual BaseGDL* OverloadIndexNew( BaseGDL*, BaseGDL*) { assert( false); return 0;} ++ virtual BaseGDL* OverloadIndexNew( BaseGDL*, BaseGDL*, BaseGDL*) { assert( false); return 0;} + + virtual void Clear() {} + virtual ~ArrayIndexT() {} @@ -390,7 +390,7 @@ // BaseGDL* Index( BaseGDL* var, IxExprListT& ixL) // { @@ -2897,7 +2912,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/arrayindex.hpp gd } diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/arrayindexlistnoassoct.hpp gdl/src/arrayindexlistnoassoct.hpp --- gdl-0.9.3/src/arrayindexlistnoassoct.hpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/arrayindexlistnoassoct.hpp 2013-02-25 17:04:24.264182457 -0700 ++++ gdl/src/arrayindexlistnoassoct.hpp 2013-03-21 14:04:04.009826878 -0600 @@ -165,7 +165,7 @@ bool ToAssocIndex( SizeT& lastIx) { @@ -3011,16 +3026,49 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/arrayindexlistnoa nParam = 0; for( SizeT i=0; isize(); ++i) -@@ -1585,7 +1585,7 @@ - { - SizeT nIter = ixList[i]->NIter( (iDim(); + SizeT varRank = varDim.Rank(); + ++ varStride = var->Dim().Stride(); ++ + if( accessType == ALLINDEXED) + { ++ baseIx = 0; ++ + nIx=ixList[0]->NIter( (0 1); +- for( SizeT i=1; iNIter( (iNIter( (iDim().Stride(); +-// varDim.Stride( varStride,acRank); // copy variables stride into varStride ++ //varDim.Stride( varStride,acRank); // copy variables stride into varStride + return; + } + + // NORMAL +- varStride = var->Dim().Stride(); + // varDim.Stride( varStride,acRank); // copy variables stride into varStride + assert( varStride[0] == 1); + +@@ -1829,7 +1830,7 @@ assert( ix->size() != 0); // must be, from compiler if( ixList.size() > MAXRANK) @@ -3029,7 +3077,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/arrayindexlistnoa nParam = 0; for( SizeT i=0; isize(); ++i) -@@ -2133,7 +2133,7 @@ +@@ -2133,7 +2134,7 @@ assert( ix->size() != 0); // must be, from compiler if( ixList.size() > MAXRANK) @@ -3038,7 +3086,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/arrayindexlistnoa nParam = 0; for( SizeT i=0; isize(); ++i) -@@ -2222,7 +2222,7 @@ +@@ -2222,7 +2223,7 @@ { SizeT nIter = ixList[i]->NIter( (i= 2 && o <= 5); + } +@@ -193,7 +233,7 @@ + } + inline bool RealType( DType t) // Float or Int + { +- return IsRealType[ t]; ++ return gdl_type_lookup::IsRealType[ t]; + // int o = DTypeOrder[ t]; + // return (o >= 2 && o <= 9); + } +@@ -203,13 +243,13 @@ + } + inline bool NumericType( DType t) // Float or Int or Complex + { +- return IsNumericType[ t]; ++ return gdl_type_lookup::IsNumericType[ t]; + // int o = DTypeOrder[ t]; + // return (o >= 2 && o <= 11); + } + inline bool ConvertableType( DType t) // everything except Struct, Ptr, Obj + { +- return IsConvertableType[ t]; ++ return gdl_type_lookup::IsConvertableType[ t]; + // int o = DTypeOrder[ t]; + // return (o >= 1 && o <= 11); + } Only in gdl-0.9.3/src: .#basegdl.hpp.1.71 +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_fun.cpp gdl/src/basic_fun.cpp +--- gdl-0.9.3/src/basic_fun.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/basic_fun.cpp 2013-03-21 14:04:04.226825875 -0600 +@@ -1,6657 +1,6658 @@ +-/*************************************************************************** +- basic_fun.cpp - basic GDL library function +- ------------------- +- begin : July 22 2002 +- copyright : (C) 2002 by Marc Schellens (exceptions see below) +- email : m_schellens@users.sf.net +- +- strtok_fun, getenv_fun, tag_names_fun, stregex_fun: +- (C) 2004 by Peter Messmer +- +-***************************************************************************/ +- +-/*************************************************************************** +- * * +- * This program is free software; you can redistribute it and/or modify * +- * it under the terms of the GNU General Public License as published by * +- * the Free Software Foundation; either version 2 of the License, or * +- * (at your option) any later version. * +- * * +- ***************************************************************************/ +- +-#include "includefirst.hpp" +- +-// get_kbrd patch +-// http://sourceforge.net/forum/forum.php?thread_id=3292183&forum_id=338691 +-#ifndef _MSC_VER +-#include +-#include +-#endif +-#include +-#include +-#include +-//#include +-#include // stregex +- +-#ifdef __APPLE__ +-# include +-# define environ (*_NSGetEnviron()) +-#endif +- +-#if defined(__FreeBSD__) || defined(__sun__) || defined(__OpenBSD__) +-extern "C" char **environ; +-#endif +- +-#include "nullgdl.hpp" +-#include "datatypes.hpp" +-#include "envt.hpp" +-#include "dpro.hpp" +-#include "dinterpreter.hpp" +-#include "basic_pro.hpp" +-#include "terminfo.hpp" +-#include "typedefs.hpp" +-#include "base64.hpp" +- +-#ifdef HAVE_LOCALE_H +-# include +-#endif +- +-/* max regexp error message length */ +-#define MAX_REGEXPERR_LENGTH 80 +- +-#ifdef _MSC_VER +-#define isfinite _finite +-#define isnan _isnan +-#define round(f) floor(f+0.5) +-int strncasecmp(const char *s1, const char *s2, size_t n) +-{ +- if (n == 0) +- return 0; +- while (n-- != 0 && tolower(*s1) == tolower(*s2)) +- { +- if (n == 0 || *s1 == '\0' || *s2 == '\0') +- break; +- s1++; +- s2++; +- } +- +- return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); +-} +-#else +-#include +-#endif +- +-namespace lib { +- +- using namespace std; +- using namespace antlr; +- +- // assumes all parameters from pOffs till end are dim +- void arr( EnvT* e, dimension& dim, SizeT pOffs=0) +- { +- +- int nParam=e->NParam()-pOffs; +- +- if( nParam <= 0) +- e->Throw( "Incorrect number of arguments."); +- +- const string BadDims="Array dimensions must be greater than 0."; +- +- +- if( nParam == 1 ) { +- +- BaseGDL* par = e->GetParDefined( pOffs); +- +- SizeT newDim; +- int ret = par->Scalar2index( newDim); +- +- if (ret < 0) throw GDLException(BadDims); +- +- if( ret > 0) { // single argument +- if (newDim < 1) throw GDLException(BadDims); +- dim << newDim; +- return; +- } +- if( ret == 0) { // array argument +- DLongGDL* ind = +- static_cast(par->Convert2(GDL_LONG, BaseGDL::COPY)); +- auto_ptr ind_guard( ind); +- //e->Guard( ind); +- +- for(SizeT i =0; i < par->N_Elements(); ++i){ +- if ((*ind)[i] < 1) throw GDLException(BadDims); +- dim << (*ind)[i]; +- } +- return; +- } +- e->Throw( "arr: should never arrive here."); +- return; +- } +- +- // max number checked in interpreter +- SizeT endIx=nParam+pOffs; +- for( SizeT i=pOffs; iGetParDefined( i); +- +- SizeT newDim; +- int ret=par->Scalar2index( newDim); +- if( ret < 1 || newDim == 0) throw GDLException(BadDims); +- dim << newDim; +- } +- } +- +- BaseGDL* bytarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DByteGDL(dim, BaseGDL::NOZERO); +- return new DByteGDL(dim); +- // } +- // catch( GDLException& ex) +- // { +-// e->Throw( ex.getMessage()); +-// } +- } +- BaseGDL* intarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DIntGDL(dim, BaseGDL::NOZERO); +- return new DIntGDL(dim); +-// } +-// catch( GDLException& ex) +-// { +-// e->Throw( "INTARR: "+ex.getMessage()); +-// } +- } +- BaseGDL* uintarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DUIntGDL(dim, BaseGDL::NOZERO); +- return new DUIntGDL(dim); +-// } +-// catch( GDLException& ex) +-// { +-// e->Throw( "UINTARR: "+ex.getMessage()); +-// } +- } +- BaseGDL* lonarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DLongGDL(dim, BaseGDL::NOZERO); +- return new DLongGDL(dim); +-/* } +- catch( GDLException& ex) +- { +- e->Throw( "LONARR: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* ulonarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DULongGDL(dim, BaseGDL::NOZERO); +- return new DULongGDL(dim); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "ULONARR: "+ex.getMessage()); +- } +- */ +-} +- BaseGDL* lon64arr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DLong64GDL(dim, BaseGDL::NOZERO); +- return new DLong64GDL(dim); +-/* } +- catch( GDLException& ex) +- { +- e->Throw( "LON64ARR: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* ulon64arr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DULong64GDL(dim, BaseGDL::NOZERO); +- return new DULong64GDL(dim); +-/* } +- catch( GDLException& ex) +- { +- e->Throw( "ULON64ARR: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* fltarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DFloatGDL(dim, BaseGDL::NOZERO); +- return new DFloatGDL(dim); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "FLTARR: "+ex.getMessage()); +- } +- */} +- BaseGDL* dblarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DDoubleGDL(dim, BaseGDL::NOZERO); +- return new DDoubleGDL(dim); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "DBLARR: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* strarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) +- e->Throw( "Keyword parameters not allowed in call."); +- return new DStringGDL(dim); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "STRARR: "+ex.getMessage()); +- } +- */ } +- BaseGDL* complexarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- if( e->KeywordSet(0)) return new DComplexGDL(dim, BaseGDL::NOZERO); +- return new DComplexGDL(dim); +- /*} +- catch( GDLException& ex) +- { +- e->Throw( "COMPLEXARR: "+ex.getMessage()); +- } +- */ } +- BaseGDL* dcomplexarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- +- if( e->KeywordSet(0)) return new DComplexDblGDL(dim, BaseGDL::NOZERO); +- return new DComplexDblGDL(dim); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "DCOMPLEXARR: "+ex.getMessage()); +- } +- */ } +- BaseGDL* ptrarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- DPtrGDL* ret; +- +-// if( e->KeywordSet(0)) +-// ret= new DPtrGDL(dim);//, BaseGDL::NOZERO); +-// else +-// if( e->KeywordSet(1)) +-// ret= new DPtrGDL(dim, BaseGDL::NOZERO); +-// else +-// return new DPtrGDL(dim); +- if( !e->KeywordSet(1)) +- return new DPtrGDL(dim); +- +- ret= new DPtrGDL(dim, BaseGDL::NOZERO); +- +- SizeT nEl=ret->N_Elements(); +- SizeT sIx=e->NewHeap(nEl); +-// #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +-{ +-// #pragma omp for +- for( SizeT i=0; iThrow( "PTRARR: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* objarr( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +-// reference counting if( e->KeywordSet(0)) return new DObjGDL(dim, BaseGDL::NOZERO); +- return new DObjGDL(dim); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "OBJARR: "+ex.getMessage()); +- } +- */ } +- +- BaseGDL* ptr_new( EnvT* e) +- { +- int nParam=e->NParam(); +- +- if( nParam > 0) +- { +- // new ptr from undefined variable is allowed as well +- BaseGDL* p= e->GetPar( 0); +- if( p == NULL) +- { +- DPtr heapID= e->NewHeap(); +- return new DPtrGDL( heapID); +- } +- +- if( e->KeywordSet(0)) // NO_COPY +- { +- BaseGDL** p= &e->GetPar( 0); +- // if( *p == NULL) +- // e->Throw( "Parameter undefined: "+ +- // e->GetParString(0)); +- +- DPtr heapID= e->NewHeap( 1, *p); +- *p=NULL; +- return new DPtrGDL( heapID); +- } +- else +- { +- BaseGDL* p= e->GetParDefined( 0); +- +- DPtr heapID= e->NewHeap( 1, p->Dup()); +- return new DPtrGDL( heapID); +- } +- } +- else +- { +- if( e->KeywordSet(1)) // ALLOCATE_HEAP +- { +- DPtr heapID= e->NewHeap(); +- return new DPtrGDL( heapID); +- } +- else +- { +- return new DPtrGDL( 0); // null ptr +- } +- } +- } +- +- BaseGDL* ptr_valid( EnvT* e) +- { +- int nParam=e->NParam(); +- +- if( e->KeywordPresent( 1)) // COUNT +- { +- e->SetKW( 1, new DLongGDL( e->Interpreter()->HeapSize())); +- } +- +- if( nParam == 0) +- { +- return e->Interpreter()->GetAllHeap(); +- } +- +- BaseGDL* p = e->GetPar( 0); +- if( p == NULL) +- { +- return new DByteGDL( 0); +- } +- +- if( e->KeywordSet( 0)) // CAST +- { +- DLongGDL* pL = dynamic_cast( p); +- auto_ptr pL_guard; +- if( pL == NULL) +- { +- pL = static_cast(p->Convert2(GDL_LONG,BaseGDL::COPY)); +- pL_guard.reset( pL); +- } +- +- SizeT nEl = pL->N_Elements(); +- DPtrGDL* ret = new DPtrGDL( pL->Dim()); // zero +- GDLInterpreter* interpreter = e->Interpreter(); +- for( SizeT i=0; iPtrValid( (*pL)[ i])) +- (*ret)[ i] = (*pL)[ i]; +- } +- return ret; +- } +- +- DPtrGDL* pPtr = dynamic_cast( p); +- if( pPtr == NULL) +- { +- return new DByteGDL( p->Dim()); // zero +- } +- +- SizeT nEl = pPtr->N_Elements(); +- DByteGDL* ret = new DByteGDL( pPtr->Dim()); // zero +- GDLInterpreter* interpreter = e->Interpreter(); +- for( SizeT i=0; iPtrValid( (*pPtr)[ i])) +- (*ret)[ i] = 1; +- } +- return ret; +- } +- +- BaseGDL* obj_valid( EnvT* e) +- { +- int nParam=e->NParam(); +- +- if( e->KeywordPresent( 1)) // COUNT +- { +- e->SetKW( 1, new DLongGDL( e->Interpreter()->ObjHeapSize())); +- } +- +- if( nParam == 0) +- { +- return e->Interpreter()->GetAllObjHeap(); +- } +- +- BaseGDL* p = e->GetPar( 0); +- if( p == NULL) +- { +- return new DByteGDL( 0); +- } +- +- if( e->KeywordSet( 0)) // CAST +- { +- DLongGDL* pL = dynamic_cast( p); +- auto_ptr pL_guard; +- if( pL == NULL) +- { +- pL = static_cast(p->Convert2(GDL_LONG,BaseGDL::COPY)); +- pL_guard.reset( pL); +- // e->Guard( pL); +- } +- +- SizeT nEl = pL->N_Elements(); +- DObjGDL* ret = new DObjGDL( pL->Dim()); // zero +- GDLInterpreter* interpreter = e->Interpreter(); +- for( SizeT i=0; iObjValid( (*pL)[ i])) +- (*ret)[ i] = (*pL)[ i]; +- } +- return ret; +- } +- +- DObjGDL* pObj = dynamic_cast( p); +- if( pObj == NULL) +- { +- return new DByteGDL( p->Dim()); // zero +- } +- +- SizeT nEl = pObj->N_Elements(); +- DByteGDL* ret = new DByteGDL( pObj->Dim()); // zero +- GDLInterpreter* interpreter = e->Interpreter(); +- for( SizeT i=0; iObjValid( (*pObj)[ i])) +- (*ret)[ i] = 1; +- } +- return ret; +- } +- +- BaseGDL* obj_new( EnvT* e) +- { +- StackGuard guard( e->Interpreter()->CallStack()); +- +- int nParam=e->NParam(); +- +- if( nParam == 0) +- { +- return new DObjGDL( 0); +- } +- +- DString objName; +- e->AssureScalarPar( 0, objName); +- +- // this is a struct name -> convert to UPPERCASE +- objName=StrUpCase(objName); +- if( objName == "IDL_OBJECT") +- objName = GDL_OBJECT_NAME; // replacement also done in GDLParser +- +- DStructDesc* objDesc=e->Interpreter()->GetStruct( objName, e->CallingNode()); +- +- DStructGDL* objStruct= new DStructGDL( objDesc, dimension()); +- +- DObj objID= e->NewObjHeap( 1, objStruct); // owns objStruct +- +- BaseGDL* newObj = new DObjGDL( objID); // the object +- +- try { +- // call INIT function +- DFun* objINIT= objDesc->GetFun( "INIT"); +- if( objINIT != NULL) +- { +- // morph to obj environment and push it onto the stack again +- e->PushNewEnvUD( objINIT, 1, &newObj); +- +- BaseGDL* res=e->Interpreter()->call_fun( objINIT->GetTree()); +- +- if( res == NULL || (!res->Scalar()) || res->False()) +- { +- GDLDelete(res); +- return new DObjGDL( 0); +- } +- GDLDelete(res); +- } +- } catch(...) { +- e->FreeObjHeap( objID); // newObj might be changed +- GDLDelete(newObj); +- throw; +- } +- +- return newObj; +- } +- +- BaseGDL* bindgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DByteGDL(dim, BaseGDL::INDGEN); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "BINDGEN: "+ex.getMessage()); +- } +- */ } +- // keywords not supported yet +- BaseGDL* indgen( EnvT* e) +- { +- dimension dim; +- +- // Defaulting to GDL_INT +- DType type = GDL_INT; +- +- static int kwIx1 = e->KeywordIx("BYTE"); +- if (e->KeywordSet(kwIx1)){ type = GDL_BYTE; } +- +- static int kwIx2 = e->KeywordIx("COMPLEX"); +- if (e->KeywordSet(kwIx2)){ type = GDL_COMPLEX; } +- +- static int kwIx3 = e->KeywordIx("DCOMPLEX"); +- if (e->KeywordSet(kwIx3)){ type = GDL_COMPLEXDBL; } +- +- static int kwIx4 = e->KeywordIx("DOUBLE"); +- if (e->KeywordSet(kwIx4)){ type = GDL_DOUBLE; } +- +- static int kwIx5 = e->KeywordIx("FLOAT"); +- if (e->KeywordSet(kwIx5)){ type = GDL_FLOAT; } +- +- static int kwIx6 = e->KeywordIx("L64"); +- if (e->KeywordSet(kwIx6)){ type = GDL_LONG64; } +- +- static int kwIx7 = e->KeywordIx("LONG"); +- if (e->KeywordSet(kwIx7)){ type = GDL_LONG; } +- +- static int kwIx8 = e->KeywordIx("STRING"); +- if (e->KeywordSet(kwIx8)){ type = GDL_STRING; } +- +- static int kwIx9 = e->KeywordIx("UINT"); +- if (e->KeywordSet(kwIx9)){ type = GDL_UINT; } +- +- static int kwIx10 = e->KeywordIx("UL64"); +- if (e->KeywordSet(kwIx10)){ type = GDL_ULONG64; } +- +- static int kwIx11 = e->KeywordIx("ULONG"); +- if (e->KeywordSet(kwIx11)){ type = GDL_ULONG; } +- +- /*try +- {*/ +- // Seeing if the user passed in a TYPE code +- static int kwIx12 = e->KeywordIx("TYPE"); +- if ( e->KeywordPresent(kwIx12)){ +- DLong temp_long; +- e->AssureLongScalarKW(kwIx12, temp_long); +- type = static_cast(temp_long); +- } +- +- arr(e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- switch(type) +- { +- case GDL_INT: return new DIntGDL(dim, BaseGDL::INDGEN); +- case GDL_BYTE: return new DByteGDL(dim, BaseGDL::INDGEN); +- case GDL_COMPLEX: return new DComplexGDL(dim, BaseGDL::INDGEN); +- case GDL_COMPLEXDBL: return new DComplexDblGDL(dim, BaseGDL::INDGEN); +- case GDL_DOUBLE: return new DDoubleGDL(dim, BaseGDL::INDGEN); +- case GDL_FLOAT: return new DFloatGDL(dim, BaseGDL::INDGEN); +- case GDL_LONG64: return new DLong64GDL(dim, BaseGDL::INDGEN); +- case GDL_LONG: return new DLongGDL(dim, BaseGDL::INDGEN); +- case GDL_STRING: { +- DULongGDL* iGen = new DULongGDL(dim, BaseGDL::INDGEN); +- return iGen->Convert2(GDL_STRING); +- } +- case GDL_UINT: return new DUIntGDL(dim, BaseGDL::INDGEN); +- case GDL_ULONG64: return new DULong64GDL(dim, BaseGDL::INDGEN); +- case GDL_ULONG: return new DULongGDL(dim, BaseGDL::INDGEN); +- default: +- e->Throw( "Invalid type code specified."); +- break; +- } +-/* } +- catch( GDLException& ex) +- { +- e->Throw( ex.getMessage()); +- }*/ +- } +- +- BaseGDL* uindgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DUIntGDL(dim, BaseGDL::INDGEN); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "UINDGEN: "+ex.getMessage()); +- } +- */ } +- BaseGDL* sindgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- DULongGDL* iGen = new DULongGDL(dim, BaseGDL::INDGEN); +- return iGen->Convert2( GDL_STRING); +-/* } +- catch( GDLException& ex) +- { +- e->Throw( "SINDGEN: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* lindgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- return new DLongGDL(dim, BaseGDL::INDGEN); +-/* } +- catch( GDLException& ex) +- { +- e->Throw( "LINDGEN: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* ulindgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DULongGDL(dim, BaseGDL::INDGEN); +-/* } +- catch( GDLException& ex) +- { +- e->Throw( "ULINDGEN: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* l64indgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DLong64GDL(dim, BaseGDL::INDGEN); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "L64INDGEN: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* ul64indgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DULong64GDL(dim, BaseGDL::INDGEN); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "UL64INDGEN: "+ex.getMessage()); +- } +- */ } +- BaseGDL* findgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DFloatGDL(dim, BaseGDL::INDGEN); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "FINDGEN: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* dindgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DDoubleGDL(dim, BaseGDL::INDGEN); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "DINDGEN: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* cindgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DComplexGDL(dim, BaseGDL::INDGEN); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "CINDGEN: "+ex.getMessage()); +- }*/ +- } +- BaseGDL* dcindgen( EnvT* e) +- { +- dimension dim; +-// try{ +- arr( e, dim); +- if (dim[0] == 0) +- throw GDLException( "Array dimensions must be greater than 0"); +- +- return new DComplexDblGDL(dim, BaseGDL::INDGEN); +- /* } +- catch( GDLException& ex) +- { +- e->Throw( "DCINDGEN: "+ex.getMessage()); +- } +- */ } +- +- // only called from CALL_FUNCTION +- // otherwise done directly in FCALL_LIB_N_ELEMENTSNode::Eval(); +- // (but must be defined anyway for LibInit() for correct parametrization) +- // N_ELEMENTS is special because on error it just returns 0L +- // (the error is just caught and dropped) +- BaseGDL* n_elements( EnvT* e) +- { +- SizeT nParam=e->NParam(1); +- +- BaseGDL* p0=e->GetPar( 0); +- +- if( p0 == NULL) return new DLongGDL( 0); +- return new DLongGDL( p0->N_Elements()); +- +-// assert( 0); +-// e->Throw("Internal error: lib::n_elements called."); +-// return NULL; // get rid of compiler warning +- } +- +- template< typename ComplexGDL, typename Complex, typename Float> +- BaseGDL* complex_fun_template( EnvT* e) +- { +- SizeT nParam=e->NParam( 1); +- if( nParam <= 2) +- { +- if( nParam == 2) +- { +- BaseGDL* p0=e->GetParDefined( 0); +- BaseGDL* p1=e->GetParDefined( 1); +- auto_ptr p0Float( static_cast +- (p0->Convert2( Float::t,BaseGDL::COPY))); +- auto_ptr p1Float( static_cast +- (p1->Convert2( Float::t,BaseGDL::COPY))); +- if( p0Float->Rank() == 0) +- { +- ComplexGDL* res = new ComplexGDL( p1Float->Dim(), +- BaseGDL::NOZERO); +- +- SizeT nE=p1Float->N_Elements(); +-// #pragma omp parallel if (nE >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nE)) +-{ +-// #pragma omp for +- for( SizeT i=0; iRank() == 0) +- { +- ComplexGDL* res = new ComplexGDL( p0Float->Dim(), +- BaseGDL::NOZERO); +- +- SizeT nE=p0Float->N_Elements(); +-// #pragma omp parallel if (nE >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nE)) +-{ +-// #pragma omp for +- for( SizeT i=0; iN_Elements() >= p1Float->N_Elements()) +- { +- ComplexGDL* res = new ComplexGDL( p1Float->Dim(), +- BaseGDL::NOZERO); +- +- SizeT nE=p1Float->N_Elements(); +-// #pragma omp parallel if (nE >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nE)) +-{ +-// #pragma omp for +- for( SizeT i=0; iDim(), +- BaseGDL::NOZERO); +- +- SizeT nE=p0Float->N_Elements(); +-// #pragma omp parallel if (nE >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nE)) +-{ +-// #pragma omp for +- for( SizeT i=0; iGetParDefined( 0); +- if (ComplexGDL::t == p0->Type() && e->GlobalPar(0)) return p0; +- return p0->Convert2( ComplexGDL::t, BaseGDL::COPY); +- } +- } +- else // GDL_COMPLEX( expr, offs, dim1,..,dim8) +- { +- BaseGDL* p0 = e->GetParDefined( 0); +- // *** WRONG: with offs data is converted bytewise +- auto_ptr p0Float(static_cast +- (p0->Convert2( Float::t, +- BaseGDL::COPY))); +- DLong offs; +- e->AssureLongScalarPar( 1, offs); +- +- dimension dim; +- arr( e, dim, 2); +- +- SizeT nElCreate=dim.NDimElements(); +- +- SizeT nElSource=p0->N_Elements(); +- +- if( (offs+2*nElCreate) > nElSource) +- e->Throw( "Specified offset to" +- " array is out of range: "+e->GetParString(0)); +- +- ComplexGDL* res=new ComplexGDL( dim, BaseGDL::NOZERO); +- +-// #pragma omp parallel if (nElCreate >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nElCreate)) +-{ +-// #pragma omp for +- for( SizeT i=0; iKeywordSet("DOUBLE")) { +- return complex_fun_template< DComplexDblGDL, DComplexDbl, DDoubleGDL>( e); +- } else { +- return complex_fun_template< DComplexGDL, DComplex, DFloatGDL>( e); +- } +-} +-BaseGDL* dcomplex_fun( EnvT* e) +-{ +- return complex_fun_template< DComplexDblGDL, DComplexDbl, DDoubleGDL>( e); +-} +- +- template< class TargetClass> +- BaseGDL* type_fun( EnvT* e) +- { +- SizeT nParam=e->NParam(1); +- +- if( nParam == 1) +- { +- BaseGDL* p0=e->GetParDefined( 0); +- +- assert( dynamic_cast< EnvUDT*>( e->Caller()) != NULL); +- +- // type_fun( expr) just convert +- if( static_cast< EnvUDT*>( e->Caller())->GetIOError() != NULL) +- return p0->Convert2( TargetClass::t, +- BaseGDL::COPY_THROWIOERROR); +- // SA: see tracker item no. 3151760 +- else if (TargetClass::t == p0->Type() && e->GlobalPar(0)) +- return p0; +- else +- return p0->Convert2( TargetClass::t, BaseGDL::COPY); +- } +- +- BaseGDL* p0=e->GetNumericParDefined( 0); +- +- // GDL_BYTE( expr, offs, dim1,..,dim8) +- DLong offs; +- e->AssureLongScalarPar( 1, offs); +- +- dimension dim; +- +- if( nParam > 2) +- arr( e, dim, 2); +- +- TargetClass* res=new TargetClass( dim, BaseGDL::NOZERO); +- +- SizeT nByteCreate=res->NBytes(); // net size of new data +- +- SizeT nByteSource=p0->NBytes(); // net size of src +- +- if( offs < 0 || (offs+nByteCreate) > nByteSource) +- { +- GDLDelete(res); +- e->Throw( "Specified offset to" +- " expression is out of range: "+e->GetParString(0)); +- } +- +- //*** POSSIBLE ERROR because of alignment here +- void* srcAddr = static_cast( static_cast(p0->DataAddr()) + +- offs); +- void* dstAddr = static_cast(&(*res)[0]); +- memcpy( dstAddr, srcAddr, nByteCreate); +- +- // char* srcAddr = reinterpret_cast(p0->DataAddr()); +- // char* dstAddr = reinterpret_cast(&(*res)[0]); +- // copy( srcAddr, srcAddr+nByteCreate, dstAddr); +- +- return res; +- } +- +- BaseGDL* byte_fun( EnvT* e) +- { +- return type_fun( e); +- } +- BaseGDL* uint_fun( EnvT* e) +- { +- return type_fun( e); +- } +- BaseGDL* long_fun( EnvT* e) +- { +- return type_fun( e); +- } +- BaseGDL* ulong_fun( EnvT* e) +- { +- return type_fun( e); +- } +- BaseGDL* long64_fun( EnvT* e) +- { +- return type_fun( e); +- } +- BaseGDL* ulong64_fun( EnvT* e) +- { +- return type_fun( e); +- } +- BaseGDL* float_fun( EnvT* e) +- { +- return type_fun( e); +- } +- BaseGDL* double_fun( EnvT* e) +- { +- return type_fun( e); +- } +- // GDL_STRING function behaves different +- BaseGDL* string_fun( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- +- if( nParam == 0) +- e->Throw( "Incorrect number of arguments."); +- +- bool printKey = e->KeywordSet( 4); +- int parOffset = 0; +- +- // SA: handling special VMS-compatibility syntax, e.g.: string(1,'$(F)') +- // (if nor FORMAT neither PRINT defined, >1 parameter, last param is scalar string +- // which begins with "$(" or "(" but is not "()" then last param [minus "$"] is treated as FORMAT) +- bool vmshack = false; +- if (!printKey && (e->GetKW(0) == NULL) && nParam > 1) +- { +- vmshack = true; +- BaseGDL* par = e->GetParDefined(nParam - 1); +- if (par->Type() == GDL_STRING && par->Scalar()) +- { +- int dollar = (*static_cast(par))[0].compare(0,2,"$("); +- if (dollar == 0 || ((*static_cast(par))[0].compare(0,1,"(") == 0 && (*static_cast(par))[0] != "()")) +- { +- e->SetKeyword("FORMAT", new DStringGDL( +- (*static_cast(par))[0].c_str() + (dollar == 0 ? 1 : 0) +- )); +- } +- } +- } +- +- BaseGDL* format_kw = e->GetKW( 0); +- bool formatKey = format_kw != NULL; +- +- if (formatKey && format_kw->Type() == GDL_STRING && (*static_cast(format_kw))[0] == "") formatKey = false; +- +- if( printKey || formatKey) // PRINT or FORMAT +- { +- stringstream os; +- +- SizeT width = 0; +- if( printKey) // otherwise: FORMAT -> width is ignored +- { +- // for /PRINT always a terminal width of 80 is assumed +- width = 80;//TermWidth(); +- } +- +- if (vmshack) +- { +- parOffset = 1; +- e->ShiftParNumbering(1); +- } +- print_os( &os, e, parOffset, width); +- if (vmshack) +- { +- e->ShiftParNumbering(-1); +- } +- +- deque buf; +- while( os.good()) +- { +- string line; +- getline( os, line); +- if( os.good()) buf.push_back( line); +- } +- +- SizeT bufSize = buf.size(); +- if( bufSize == 0) +- e->Throw( "Internal error: print buffer empty."); +- +- if( bufSize > 1) +- { +- DStringGDL* retVal = +- new DStringGDL( dimension( bufSize), BaseGDL::NOZERO); +- +- for( SizeT i=0; i conversion +- { +- BaseGDL* p0 = e->GetParDefined( 0); +- // SA: see tracker item no. 3151760 +- if (p0->Type() == GDL_STRING && e->GlobalPar(0)) return p0; +- return p0->Convert2( GDL_STRING, BaseGDL::COPY); +- } +- else // concatenation +- { +- DString s; +- for( SizeT i=0; iGetParDefined( i); +- DStringGDL* sP = static_cast +- ( p->Convert2(GDL_STRING, +- BaseGDL::COPY_BYTE_AS_INT)); +- +- SizeT nEl = sP->N_Elements(); +- for( SizeT e=0; eIfDefGetKWAs( 0); +- if (type != NULL) { +- int typ = (*type)[0]; +- if (typ == GDL_BYTE) +- { +- // SA: slow yet simple solution using GDL_BYTE->GDL_INT->GDL_BYTE conversion +- return (e->KeywordSet(1) && e->GetPar(0)->Type() == GDL_STRING) +- ? type_fun( e)->Convert2(GDL_BYTE, BaseGDL::CONVERT) +- : type_fun( e); +- } +- if (typ == 0 || typ == GDL_INT) return type_fun( e); +- if (typ == GDL_UINT) return type_fun( e); +- if (typ == GDL_LONG) return type_fun( e); +- if (typ == GDL_ULONG) return type_fun( e); +- if (typ == GDL_LONG64) return type_fun( e); +- if (typ == GDL_ULONG64) return type_fun( e); +- if (typ == GDL_FLOAT) return type_fun( e); +- if (typ == GDL_DOUBLE) return type_fun( e); +- if (typ == GDL_COMPLEX) return type_fun( e); +- if (typ == GDL_COMPLEXDBL) return type_fun( e); +- if (typ == GDL_STRING) +- { +- // SA: calling GDL_STRING() with correct parameters +- static int stringIx = LibFunIx("STRING"); +- +- assert( stringIx >= 0); +- +- EnvT* newEnv= new EnvT(e, libFunList[stringIx], NULL); +- +- auto_ptr guard( newEnv); +- +- newEnv->SetNextPar(&e->GetPar(0)); // pass as global +- if (e->KeywordSet(1) && e->GetPar(0)->Type() == GDL_BYTE) +- newEnv->SetKeyword("PRINT", new DIntGDL(1)); +-// e->Interpreter()->CallStack().push_back( newEnv); +- return static_cast(newEnv->GetPro())->Fun()(newEnv); +- } +- e->Throw( "Improper TYPE value."); +- } +- return type_fun( e); +- } +- +- BaseGDL* call_function( EnvT* e) +- { +- int nParam=e->NParam(); +- if( nParam == 0) +- e->Throw( "No function specified."); +- +- DString callF; +- e->AssureScalarPar( 0, callF); +- +- // this is a function name -> convert to UPPERCASE +- callF = StrUpCase( callF); +- +- // first search library funcedures +- int funIx=LibFunIx( callF); +- if( funIx != -1) +- { +-// e->PushNewEnv( libFunList[ funIx], 1); +- // make the call +-// EnvT* newEnv = static_cast(e->Interpreter()->CallStack().back()); +- +- // handle direct call functions +- if( libFunList[ funIx]->DirectCall()) +- { +- BaseGDL* directCallParameter = e->GetParDefined(1); +- BaseGDL* res = +- static_cast(libFunList[ funIx])->FunDirect()(directCallParameter, true /*isReference*/); +- return res; +- } +- else +- { +- EnvT* newEnv = e->NewEnv( libFunList[ funIx], 1); +- auto_ptr guard( newEnv); +- return static_cast(newEnv->GetPro())->Fun()(newEnv); +- } +- } +- else +- { +- // no direct call here +- +- StackGuard guard( e->Interpreter()->CallStack()); +- +- funIx = GDLInterpreter::GetFunIx( callF); +- +- e->PushNewEnvUD( funList[ funIx], 1); +- +- // make the call +- EnvUDT* newEnv = static_cast(e->Interpreter()->CallStack().back()); +- return e->Interpreter()->call_fun(static_cast(newEnv->GetPro())->GetTree()); +- } +- } +- +- BaseGDL* call_method_function( EnvT* e) +- { +- StackGuard guard( e->Interpreter()->CallStack()); +- +- int nParam=e->NParam(); +- if( nParam < 2) +- e->Throw( "Name and object reference" +- " must be specified."); +- +- DString callP; +- e->AssureScalarPar( 0, callP); +- +- // this is a procedure name -> convert to UPPERCASE +- callP = StrUpCase( callP); +- +- DStructGDL* oStruct = e->GetObjectPar( 1); +- +- DFun* method= oStruct->Desc()->GetFun( callP); +- +- if( method == NULL) +- e->Throw( "Method not found: "+callP); +-// // // /**/ +- e->PushNewEnvUD( method, 2, &e->GetPar( 1)); +- +- // make the call +- return e->Interpreter()->call_fun( method->GetTree()); +- } +- +- +- +- BaseGDL* execute( EnvT* e) +- { +- int nParam=e->NParam( 1); +- +- bool quietCompile = false; +- if( nParam == 2) +- { +- BaseGDL* p1 = e->GetParDefined( 1); +- +- if( !p1->Scalar()) +- e->Throw( "Expression must be scalar in this context: "+ +- e->GetParString(1)); +- +- quietCompile = p1->True(); +- } +- +- if (e->GetParDefined(0)->Rank() != 0) +- e->Throw("Expression must be scalar in this context: "+e->GetParString(0)); +- +- DString line; +- e->AssureScalarPar( 0, line); +- +- // remove current environment (own one) +- assert( dynamic_cast(e->Caller()) != NULL); +- EnvUDT* caller = static_cast(e->Caller()); +-// e->Interpreter()->CallStack().pop_back(); +- +-// wrong: e is guarded, do not delete it here +-// delete e; +- +- istringstream istr(line+"\n"); +- +- RefDNode theAST; +- try { +- GDLLexer lexer(istr, "", caller->CompileOpt()); +- GDLParser& parser=lexer.Parser(); +- +- parser.interactive(); +- +- theAST=parser.getAST(); +- } +- catch( GDLException& ex) +- { +- if( !quietCompile) GDLInterpreter::ReportCompileError( ex); +- return new DIntGDL( 0); +- } +- catch( ANTLRException ex) +- { +- if( !quietCompile) cerr << "EXECUTE: Lexer/Parser exception: " << +- ex.getMessage() << endl; +- return new DIntGDL( 0); +- } +- +- if( theAST == NULL) return new DIntGDL( 1); +- +- RefDNode trAST; +- try +- { +- GDLTreeParser treeParser( caller); +- +- treeParser.interactive(theAST); +- +- trAST=treeParser.getAST(); +- } +- catch( GDLException& ex) +- { +- if( !quietCompile) GDLInterpreter::ReportCompileError( ex); +- return new DIntGDL( 0); +- } +- +- catch( ANTLRException ex) +- { +- if( !quietCompile) cerr << "EXECUTE: Compiler exception: " << +- ex.getMessage() << endl; +- return new DIntGDL( 0); +- } +- +- if( trAST == NULL) return new DIntGDL( 1); +- +- int nForLoopsIn = caller->NForLoops(); +- try +- { +- ProgNodeP progAST = ProgNode::NewProgNode( trAST); +- auto_ptr< ProgNode> progAST_guard( progAST); +- +- int nForLoops = ProgNode::NumberForLoops( progAST, nForLoopsIn); +- caller->ResizeForLoops( nForLoops); +- +- progAST->setLine( e->GetLineNumber()); +- +- RetCode retCode = caller->Interpreter()->execute( progAST); +- +- caller->ResizeForLoops( nForLoopsIn); +- +- if( retCode == RC_OK) +- return new DIntGDL( 1); +- else +- return new DIntGDL( 0); +- } +- catch( GDLException& ex) +- { +- caller->ResizeForLoops( nForLoopsIn); +- // are we throwing to target environment? +-// if( ex.GetTargetEnv() == NULL) +- if( !quietCompile) cerr << "EXECUTE: " << +- ex.getMessage() << endl; +- return new DIntGDL( 0); +- } +- catch( ANTLRException ex) +- { +- caller->ResizeForLoops( nForLoopsIn); +- +- if( !quietCompile) cerr << "EXECUTE: Interpreter exception: " << +- ex.getMessage() << endl; +- return new DIntGDL( 0); +- } +- +- return new DIntGDL( 0); // control flow cannot reach here - compiler shut up +- } +- +- BaseGDL* assoc( EnvT* e) +- { +- SizeT nParam=e->NParam( 2); +- +- DLong lun; +- e->AssureLongScalarPar( 0, lun); +- +- bool stdLun = check_lun( e, lun); +- if( stdLun) +- e->Throw( "File unit does not allow" +- " this operation. Unit: "+i2s( lun)); +- +- DLong offset = 0; +- if( nParam >= 3) e->AssureLongScalarPar( 2, offset); +- +- BaseGDL* arr = e->GetParDefined( 1); +- +- if( arr->StrictScalar()) +- e->Throw( "Scalar variable not allowed in this" +- " context: "+e->GetParString(1)); +- +- return arr->AssocVar( lun, offset); +- } +- +- // gdl_ naming because of weired namespace problem in MSVC +- BaseGDL* gdl_logical_and( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- if( nParam != 2) +- e->Throw( +- "Incorrect number of arguments."); +- +- BaseGDL* e1=e->GetParDefined( 0);//, "LOGICAL_AND"); +- BaseGDL* e2=e->GetParDefined( 1);//, "LOGICAL_AND"); +- +- ULong nEl1 = e1->N_Elements(); +- ULong nEl2 = e2->N_Elements(); +- +- Data_* res; +- +- if( e1->Scalar()) +- { +- if( e1->LogTrue(0)) +- { +- res= new Data_( e2->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl2; i++) +- (*res)[i] = e2->LogTrue( i) ? 1 : 0; +-} +- } +- else +- { +- return new Data_( e2->Dim()); +- } +- } +- else if( e2->Scalar()) +- { +- if( e2->LogTrue(0)) +- { +- res= new Data_( e1->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl1; i++) +- (*res)[i] = e1->LogTrue( i) ? 1 : 0; +-} +- } +- else +- { +- return new Data_( e1->Dim()); +- } +- } +- else if( nEl2 < nEl1) +- { +- res= new Data_( e2->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl2; i++) +- (*res)[i] = (e1->LogTrue( i) && e2->LogTrue( i)) ? 1 : 0; +-} +- } +- else // ( nEl2 >= nEl1) +- { +- res= new Data_( e1->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl1; i++) +- (*res)[i] = (e1->LogTrue( i) && e2->LogTrue( i)) ? 1 : 0; +-} +- } +- return res; +- } +- +- // gdl_ naming because of weired namespace problem in MSVC +- BaseGDL* gdl_logical_or( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- if( nParam != 2) +- e->Throw( +- "Incorrect number of arguments."); +- +- BaseGDL* e1=e->GetParDefined( 0);//, "LOGICAL_OR"); +- BaseGDL* e2=e->GetParDefined( 1);//, "LOGICAL_OR"); +- +- ULong nEl1 = e1->N_Elements(); +- ULong nEl2 = e2->N_Elements(); +- +- Data_* res; +- +- if( e1->Scalar()) +- { +- if( e1->LogTrue(0)) +- { +- res= new Data_( e2->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl2; i++) +- (*res)[i] = 1; +-} +- } +- else +- { +- res= new Data_( e2->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl2; i++) +- (*res)[i] = e2->LogTrue( i) ? 1 : 0; +-} +- } +- } +- else if( e2->Scalar()) +- { +- if( e2->LogTrue(0)) +- { +- res= new Data_( e1->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl1; i++) +- (*res)[i] = 1; +-} +- } +- else +- { +- res= new Data_( e1->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl1; i++) +- (*res)[i] = e1->LogTrue( i) ? 1 : 0; +-} +- } +- } +- else if( nEl2 < nEl1) +- { +- res= new Data_( e2->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl2; i++) +- (*res)[i] = (e1->LogTrue( i) || e2->LogTrue( i)) ? 1 : 0; +-} +- } +- else // ( nEl2 >= nEl1) +- { +- res= new Data_( e1->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl1; i++) +- (*res)[i] = (e1->LogTrue( i) || e2->LogTrue( i)) ? 1 : 0; +-} +- } +- return res; +- } +- +- BaseGDL* logical_true( BaseGDL* e1, bool isReference)//( EnvT* e); +- { +- assert( e1 != NULL); +- assert( e1->N_Elements() > 0); +- +- +-// SizeT nParam=e->NParam(); +-// if( nParam != 1) +-// e->Throw( +-// "Incorrect number of arguments."); +-// +-// BaseGDL* e1=e->GetParDefined( 0);//, "LOGICAL_TRUE"); +-// +- ULong nEl1 = e1->N_Elements(); +- +- Data_* res = new Data_( e1->Dim(), BaseGDL::NOZERO); +-// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) +-{ +-// #pragma omp for +- for( SizeT i=0; i < nEl1; i++) +- (*res)[i] = e1->LogTrue( i) ? 1 : 0; +-} +- return res; +- } +- +- BaseGDL* replicate( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- if( nParam < 2) +- e->Throw( "Incorrect number of arguments."); +- dimension dim; +- arr( e, dim, 1); +- +- BaseGDL* p0=e->GetParDefined( 0);//, "REPLICATE"); +- if( !p0->Scalar()) +- e->Throw( "Expression must be a scalar in this context: "+ +- e->GetParString(0)); +- +- return p0->New( dim, BaseGDL::INIT); +- } +- +- BaseGDL* strtrim( EnvT* e) +- { +- SizeT nParam = e->NParam( 1);//, "STRTRIM"); +- +- BaseGDL* p0 = e->GetPar( 0); +- if( p0 == NULL) +- e->Throw( +- "Variable is undefined: "+ +- e->GetParString(0)); +- DStringGDL* p0S = static_cast +- (p0->Convert2(GDL_STRING,BaseGDL::COPY)); +- +- DLong mode = 0; +- if( nParam == 2) +- { +- BaseGDL* p1 = e->GetPar( 1); +- if( p1 == NULL) +- e->Throw( +- "Variable is undefined: "+e->GetParString(1)); +- if( !p1->Scalar()) +- e->Throw( +- "Expression must be a " +- "scalar in this context: "+ +- e->GetParString(1)); +- DLongGDL* p1L = static_cast +- (p1->Convert2(GDL_LONG,BaseGDL::COPY)); +- +- mode = (*p1L)[ 0]; +- +- GDLDelete(p1L); +- +- if( mode < 0 || mode > 2) +- { +- ostringstream os; +- p1->ToStream( os); +- e->Throw( +- "Value of <"+ p1->TypeStr() + +- " ("+os.str()+ +- ")> is out of allowed range."); +- } +- } +- +- SizeT nEl = p0S->N_Elements(); +- +- if( mode == 2) // both +- { +-TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if ((nEl*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) +-{ +-#pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) +-{ +-#pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) +-{ +-#pragma omp for +- for( int i=0; iNParam( 1); +- +- DStringGDL* p0S = e->GetParAs( 0); +- +- bool removeAll = e->KeywordSet(0); +- +- DStringGDL* res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); +- +- SizeT nEl = p0S->N_Elements(); +-TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if ((nEl*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) +-{ +-#pragma omp for +- for( int i=0; iNParam( 2);//, "STRPOS"); +- +- bool reverseOffset = e->KeywordSet(0); // REVERSE_OFFSET +- bool reverseSearch = e->KeywordSet(1); // REVERSE_SEARCH +- +- DStringGDL* p0S = e->GetParAs( 0); +- +- DString searchString; +- // e->AssureScalarPar( 1, searchString); +- DStringGDL* sStr = e->GetParAs( 1); +- if( !sStr->Scalar( searchString)) +- e->Throw( "Search string must be a scalar or one element array: "+ +- e->GetParString( 1)); +- +- unsigned long pos = string::npos; +- if( nParam > 2) +-{ +- BaseGDL* p2 = e->GetParDefined(2); +-// if( p2 != NULL) //e->AssureLongScalarPar( 2,posDLong); +-// { +- const SizeT pIx = 2; +- BaseGDL* p = e->GetParDefined( pIx); +- DLongGDL* lp = static_cast(p->Convert2( GDL_LONG, BaseGDL::COPY)); +- auto_ptr guard_lp( lp); +- DLong scalar; +- if( !lp->Scalar( scalar)) +- throw GDLException("Parameter must be a scalar in this context: "+ +- e->GetParString(pIx)); +- pos = scalar; +- } +- +- DLongGDL* res = new DLongGDL( p0S->Dim(), BaseGDL::NOZERO); +- +- SizeT nSrcStr = p0S->N_Elements(); +-TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if ((nSrcStr*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nSrcStr*10))) +-{ +-#pragma omp for +- for( long i=0; iNParam( 2);//, "STRMID"); +- +- bool reverse = e->KeywordSet(0); +- +- DStringGDL* p0S = e->GetParAs( 0); +- DLongGDL* p1L = e->GetParAs( 1); +- +- BaseGDL* p2 = e->GetPar( 2); +- DLongGDL* p2L = NULL; +- if( p2 != NULL) p2L = e->GetParAs( 2); +- +- DLong scVal1; +- bool sc1 = p1L->Scalar( scVal1); +- +- DLong scVal2 = numeric_limits::max(); +- bool sc2 = true; +- if( p2L != NULL) +- { +- DLong scalar; +- sc2 = p2L->Scalar( scalar); +- scVal2 = scalar; +- } +- +- DLong stride; +- if( !sc1 && !sc2) +- { +- stride = p1L->Dim( 0); +- if( stride != p2L->Dim( 0)) +- e->Throw( +- "Starting offset and length arguments " +- "have incompatible first dimension."); +- } +- else +- { +- // at least one scalar, p2L possibly NULL +- if( p2L == NULL) +- stride = p1L->Dim( 0); +- else +- stride = max( p1L->Dim( 0), p2L->Dim( 0)); +- +- stride = (stride > 0)? stride : 1; +- } +- +- dimension resDim( p0S->Dim()); +- if( stride > 1) +- resDim >> stride; +- +- DStringGDL* res = new DStringGDL( resDim, BaseGDL::NOZERO); +- +- SizeT nEl1 = p1L->N_Elements(); +- SizeT nEl2 = (sc2)? 1 : p2L->N_Elements(); +- +- SizeT nSrcStr = p0S->N_Elements(); +-TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if ((nSrcStr*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nSrcStr*10))) default( shared) +-{ +-#pragma omp for +- for( long i=0; iN_Elements() > 0); +- +-// e->NParam( 1);//, "STRLOWCASE"); +- +-// DStringGDL* p0S = e->GetParAs( 0); +- DStringGDL* p0S; +- DStringGDL* res; +-// auto_ptr guard; +- +- if( p0->Type() == GDL_STRING) +- { +- p0S = static_cast( p0); +- if( !isReference) +- res = p0S; +- else +- res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); +- } +- else +- { +- p0S = static_cast( p0->Convert2( GDL_STRING, BaseGDL::COPY)); +- res = p0S; +-// guard.reset( p0S); +- } +- +-// DStringGDL* res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); +- +- SizeT nEl = p0S->N_Elements(); +- +- if( res == p0S) +- { +-TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if ((nEl*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) +-{ +-#pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) +-{ +-#pragma omp for +- for( int i=0; iN_Elements() > 0); +- +-// e->NParam( 1);//, "STRLOWCASE"); +- +-// DStringGDL* p0S = e->GetParAs( 0); +- DStringGDL* p0S; +- DStringGDL* res; +-// auto_ptr guard; +- +- if( p0->Type() == GDL_STRING) +- { +- p0S = static_cast( p0); +- if( !isReference) +- res = p0S; +- else +- res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); +- } +- else +- { +- p0S = static_cast( p0->Convert2( GDL_STRING, BaseGDL::COPY)); +- res = p0S; +-// guard.reset( p0S); +- } +- +-// DStringGDL* res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); +- +- SizeT nEl = p0S->N_Elements(); +- +- if( res == p0S) +- { +-TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if ((nEl*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) +-{ +-#pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) +-{ +-#pragma omp for +- for( int i=0; iN_Elements() > 0); +- +-// e->NParam( 1);//, "STRLEN"); +- +- DStringGDL* p0S; +- auto_ptr guard; +- +- if( p0->Type() == GDL_STRING) +- p0S = static_cast( p0); +- else +- { +- p0S = static_cast( p0->Convert2( GDL_STRING, BaseGDL::COPY)); +- guard.reset( p0S); +- } +- +- DLongGDL* res = new DLongGDL( p0S->Dim(), BaseGDL::NOZERO); +- +- SizeT nEl = p0S->N_Elements(); +-// #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +-{ +-// #pragma omp for +- for( SizeT i=0; iNParam( 1); +- +- DStringGDL* p0S = e->GetParAs( 0); +- SizeT nEl = p0S->N_Elements(); +- +- DString delim = ""; +- if( nParam > 1) +- e->AssureStringScalarPar( 1, delim); +- +- bool single = e->KeywordSet( 0); // SINGLE +- +- if( single) +- { +- DStringGDL* res = new DStringGDL( (*p0S)[0]); +- DString& scl = (*res)[0]; +- +- for( SizeT i=1; iDim()); +- resDim.Purge(); +- +- SizeT stride = resDim.Stride( 1); +- +- resDim.Remove( 0); +- +- DStringGDL* res = new DStringGDL( resDim, BaseGDL::NOZERO); +- for( SizeT src=0, dst=0; srcNParam( 1);//, "WHERE"); +- +- BaseGDL* p0 = e->GetParDefined( 0);//, "WHERE"); +- +- SizeT nEl = p0->N_Elements(); +- +- SizeT count; +- +- static int nullIx = e->KeywordIx("NULL"); +- bool nullKW = e->KeywordSet(nullIx); +- +- DLong* ixList = p0->Where( e->KeywordPresent( 0), count); +- ArrayGuard guard( ixList); +- SizeT nCount = nEl - count; +- +- if( e->KeywordPresent( 0)) // COMPLEMENT +- { +- if( nCount == 0) +- { +- if( nullKW) +- e->SetKW( 0, NullGDL::GetSingleInstance()); +- else +- e->SetKW( 0, new DLongGDL( -1)); +- } +- else +- { +- DLongGDL* cIxList = new DLongGDL( dimension( &nCount, 1), +- BaseGDL::NOZERO); +- +- SizeT cIx = nEl - 1; +-// #pragma omp parallel if (nCount >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCount)) +-{ +-// #pragma omp for +- for( SizeT i=0; iSetKW( 0, cIxList); +- } +- } +- +- if( e->KeywordPresent( 1)) // NCOMPLEMENT +- { +- e->SetKW( 1, new DLongGDL( nCount)); +- } +- +- if( nParam == 2) +- { +- e->SetPar( 1, new DLongGDL( count)); +- } +- +- if( count == 0) +- { +- if( nullKW) +- return NullGDL::GetSingleInstance(); +- return new DLongGDL( -1); +- } +- +- return new DLongGDL( ixList, count); +- +- // DLongGDL* res = new DLongGDL( dimension( &count, 1), +- // BaseGDL::NOZERO); +- // for( SizeT i=0; i(e->Caller()); +- if( caller == NULL) return new DLongGDL( 0); +- DLong nP = caller->NParam(); +- if( caller->IsObject()) +- return new DLongGDL( nP-1); // "self" is not counted +- return new DLongGDL( nP); +- } +- +- BaseGDL* keyword_set( EnvT* e) +- { +- e->NParam( 1);//, "KEYWORD_SET"); +- +- BaseGDL* p0 = e->GetPar( 0); +- if( p0 == NULL) return new DIntGDL( 0); +- if( !p0->Scalar()) return new DIntGDL( 1); +- if( p0->Type() == GDL_STRUCT) return new DIntGDL( 1); +- if( p0->LogTrue()) return new DIntGDL( 1); +- return new DIntGDL( 0); +- } +- +- // passing 2nd argument by value is slightly better for float and double, +- // but incur some overhead for the complex class. +- template inline void AddOmitNaN(T& dest, T value) +-{ +- if (isfinite(value)) +-{ +-// #pragma omp atomic +- dest += value; +-} +-} +- template inline void AddOmitNaNCpx(T& dest, T value) +- { +-// #pragma omp atomic +- dest += T(isfinite(value.real())? value.real() : 0, +- isfinite(value.imag())? value.imag() : 0); +- } +- template<> inline void AddOmitNaN(DComplex& dest, DComplex value) +- { AddOmitNaNCpx(dest, value); } +- template<> inline void AddOmitNaN(DComplexDbl& dest, DComplexDbl value) +- { AddOmitNaNCpx(dest, value); } +- +- template inline void NaN2Zero(T& value) +- { if (!isfinite(value)) value = 0; } +- template inline void NaN2ZeroCpx(T& value) +- { +- value = T(isfinite(value.real())? value.real() : 0, +- isfinite(value.imag())? value.imag() : 0); +- } +- template<> inline void NaN2Zero(DComplex& value) +- { NaN2ZeroCpx< DComplex>(value); } +- template<> inline void NaN2Zero(DComplexDbl& value) +- { NaN2ZeroCpx< DComplexDbl>(value); } +- +- // total over all elements +- template +- BaseGDL* total_template( T* src, bool omitNaN) +- { +- if (!omitNaN) return new T(src->Sum()); +- typename T::Ty sum = 0; +- SizeT nEl = src->N_Elements(); +-TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared(sum) +-{ +-#pragma omp for +- for ( int i=0; i +- BaseGDL* total_cu_template( T* res, bool omitNaN) +- { +- SizeT nEl = res->N_Elements(); +- if (omitNaN) +- { +-// #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +-{ +-// #pragma omp for +- for( SizeT i=0; i +- BaseGDL* total_over_dim_template( T* src, +- const dimension& srcDim, +- SizeT sumDimIx, +- bool omitNaN) +- { +- SizeT nEl = src->N_Elements(); +- +- // get dest dim and number of summations +- dimension destDim = srcDim; +- SizeT nSum = destDim.Remove( sumDimIx); +- +- T* res = new T( destDim); // zero fields +- +- // sumStride is also the number of linear src indexing +- SizeT sumStride = srcDim.Stride( sumDimIx); +- SizeT outerStride = srcDim.Stride( sumDimIx + 1); +- SizeT sumLimit = nSum * sumStride; +- SizeT rIx=0; +- for( SizeT o=0; o < nEl; o += outerStride) +- for( SizeT i=0; i < sumStride; ++i) +- { +- SizeT oi = o+i; +- SizeT oiLimit = sumLimit + oi; +- if( omitNaN) +- { +- for( SizeT s=oi; s +- BaseGDL* total_over_dim_cu_template( T* res, +- SizeT sumDimIx, +- bool omitNaN) +- { +- SizeT nEl = res->N_Elements(); +- const dimension& resDim = res->Dim(); +- if (omitNaN) +- { +- for( SizeT i=0; iNParam( 1);//, "TOTAL"); +- +- BaseGDL* p0 = e->GetParDefined( 0);//, "TOTAL"); +- +- SizeT nEl = p0->N_Elements(); +- if( nEl == 0) +- e->Throw( "Variable is undefined: "+e->GetParString(0)); +- +- if( p0->Type() == GDL_STRING) +- e->Throw( "String expression not allowed " +- "in this context: "+e->GetParString(0)); +- +- static int cumIx = e->KeywordIx( "CUMULATIVE"); +- static int intIx = e->KeywordIx("INTEGER"); +- static int doubleIx = e->KeywordIx( "DOUBLE"); +- static int nanIx = e->KeywordIx( "NAN"); +- static int preserveIx = e->KeywordIx( "PRESERVE_TYPE"); +- +- bool cumulative = e->KeywordSet( cumIx); +- bool intRes = e->KeywordSet( intIx); +- bool doubleRes = e->KeywordSet( doubleIx); +- bool nan = e->KeywordSet( nanIx); +- bool preserve = e->KeywordSet( preserveIx); +- +- DLong sumDim = 0; +- if( nParam == 2) +- e->AssureLongScalarPar( 1, sumDim); +- +- if( sumDim == 0) +- { +- if( !cumulative) +- { +- if (preserve) +- { +- switch (p0->Type()) +- { +- case GDL_BYTE: return total_template(static_cast(p0), false); +- case GDL_INT: return total_template(static_cast(p0), false); +- case GDL_UINT: return total_template(static_cast(p0), false); +- case GDL_LONG: return total_template(static_cast(p0), false); +- case GDL_ULONG: return total_template(static_cast(p0), false); +- case GDL_LONG64: return total_template(static_cast(p0), false); +- case GDL_ULONG64: return total_template(static_cast(p0), false); +- case GDL_FLOAT: return total_template(static_cast(p0), nan); +- case GDL_DOUBLE: return total_template(static_cast(p0), nan); +- case GDL_COMPLEX: return total_template(static_cast(p0), nan); +- case GDL_COMPLEXDBL: return total_template(static_cast(p0), nan); +- default: assert(false); +- } +- } +- +- // Integer parts by Erin Sheldon +- // In IDL total(), the INTEGER keyword takes precedence +- if( intRes ) +- { +- // We use GDL_LONG64 unless the input is GDL_ULONG64 +- if ( p0->Type() == GDL_LONG64 ) +- { +- return total_template +- ( static_cast(p0), nan ); +- } +- if ( p0->Type() == GDL_ULONG64 ) +- { +- return total_template +- ( static_cast(p0), nan ); +- } +- +- // Conver to Long64 +- DLong64GDL* p0L64 = static_cast +- (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); +- auto_ptr guard( p0L64); +- return total_template( p0L64, nan); +- +- } // integer results +- +- +- if( p0->Type() == GDL_DOUBLE) +- { +- return total_template +- ( static_cast(p0), nan); +- } +- if( p0->Type() == GDL_COMPLEXDBL) +- { +- return total_template +- ( static_cast(p0), nan); +- } +- +- if( !doubleRes) +- { +- if( p0->Type() == GDL_FLOAT) +- { +- return total_template +- ( static_cast(p0), nan); +- } +- if( p0->Type() == GDL_COMPLEX) +- { +- return total_template +- ( static_cast(p0), nan); +- } +- DFloatGDL* p0F = static_cast +- (p0->Convert2( GDL_FLOAT,BaseGDL::COPY)); +- auto_ptr guard( p0F); +- return total_template( p0F, false); +- } +- if( p0->Type() == GDL_COMPLEX) +- { +- DComplexDblGDL* p0D = static_cast +- (p0->Convert2( GDL_COMPLEXDBL,BaseGDL::COPY)); +- auto_ptr p0D_guard( p0D); +- return total_template( p0D, nan); +- } +- +- DDoubleGDL* p0D = static_cast +- (p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)); +- auto_ptr p0D_guard( p0D); +- return total_template( p0D, nan); +- } +- else // cumulative +- { +- if (preserve) +- { +- switch (p0->Type()) +- { +- case GDL_BYTE: return total_cu_template(static_cast(p0)->Dup(), false); +- case GDL_INT: return total_cu_template(static_cast(p0)->Dup(), false); +- case GDL_UINT: return total_cu_template(static_cast(p0)->Dup(), false); +- case GDL_LONG: return total_cu_template(static_cast(p0)->Dup(), false); +- case GDL_ULONG: return total_cu_template(static_cast(p0)->Dup(), false); +- case GDL_LONG64: return total_cu_template(static_cast(p0)->Dup(), false); +- case GDL_ULONG64: return total_cu_template(static_cast(p0)->Dup(), false); +- case GDL_FLOAT: return total_cu_template(static_cast(p0)->Dup(), nan); +- case GDL_DOUBLE: return total_cu_template(static_cast(p0)->Dup(), nan); +- case GDL_COMPLEX: return total_cu_template(static_cast(p0)->Dup(), nan); +- case GDL_COMPLEXDBL: return total_cu_template(static_cast(p0)->Dup(), nan); +- default: assert(false); +- } +- } +- +- // INTEGER keyword takes precedence +- if( intRes ) +- { +- // We use GDL_LONG64 unless the input is GDL_ULONG64 +- if ( p0->Type() == GDL_LONG64 ) +- { +- return total_cu_template +- ( static_cast(p0)->Dup(), nan ); +- } +- if ( p0->Type() == GDL_ULONG64 ) +- { +- return total_cu_template +- ( static_cast(p0)->Dup(), nan ); +- } +- +- // Convert to Long64 +- return total_cu_template +- ( static_cast +- (p0->Convert2( GDL_LONG64, BaseGDL::COPY)), nan); +- +- } // integer results +- +- +- // special case as GDL_DOUBLE type overrides /GDL_DOUBLE +- if( p0->Type() == GDL_DOUBLE) +- { +- return total_cu_template< DDoubleGDL> +- ( static_cast(p0)->Dup(), nan); +- } +- if( p0->Type() == GDL_COMPLEXDBL) +- { +- return total_cu_template< DComplexDblGDL> +- ( static_cast(p0)->Dup(), nan); +- } +- +- +- +- if( !doubleRes) +- { +- // special case for GDL_FLOAT has no advantage here +- if( p0->Type() == GDL_COMPLEX) +- { +- return total_cu_template< DComplexGDL> +- ( static_cast(p0)->Dup(), nan); +- } +- return total_cu_template< DFloatGDL> +- ( static_cast( p0->Convert2(GDL_FLOAT, +- BaseGDL::COPY)), nan); +- } +- if( p0->Type() == GDL_COMPLEX) +- { +- return total_cu_template< DComplexDblGDL> +- ( static_cast(p0->Convert2( GDL_COMPLEXDBL, +- BaseGDL::COPY)), nan); +- } +- return total_cu_template< DDoubleGDL> +- ( static_cast(p0->Convert2( GDL_DOUBLE, +- BaseGDL::COPY)), nan); +- } +- } +- +- // total over sumDim +- dimension srcDim = p0->Dim(); +- SizeT srcRank = srcDim.Rank(); +- +- if( sumDim < 1 || sumDim > srcRank) +- e->Throw( +- "Array must have "+i2s(sumDim)+ +- " dimensions: "+e->GetParString(0)); +- +- if( !cumulative) +- { +- if (preserve) +- { +- switch (p0->Type()) +- { +- case GDL_BYTE: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); +- case GDL_INT: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); +- case GDL_UINT: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); +- case GDL_LONG: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); +- case GDL_ULONG: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); +- case GDL_LONG64: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); +- case GDL_ULONG64: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); +- case GDL_FLOAT: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, nan); +- case GDL_DOUBLE: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, nan); +- case GDL_COMPLEX: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, nan); +- case GDL_COMPLEXDBL: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, nan); +- default: assert(false); +- } +- } +- +- // INTEGER keyword takes precedence +- if( intRes ) +- { +- // We use GDL_LONG64 unless the input is GDL_ULONG64 +- if ( p0->Type() == GDL_LONG64 ) +- { +- return total_over_dim_template +- ( static_cast(p0), srcDim, sumDim-1, nan ); +- } +- if ( p0->Type() == GDL_ULONG64 ) +- { +- return total_over_dim_template +- ( static_cast(p0), srcDim, sumDim-1, nan ); +- } +- +- // Conver to Long64 +- DLong64GDL* p0L64 = static_cast +- (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); +- +- auto_ptr p0L64_guard( p0L64); +- return total_over_dim_template +- ( p0L64, srcDim, sumDim-1, nan); +- +- } // integer results +- +- +- if( p0->Type() == GDL_DOUBLE) +- { +- return total_over_dim_template< DDoubleGDL> +- ( static_cast(p0), srcDim, sumDim-1, nan); +- } +- if( p0->Type() == GDL_COMPLEXDBL) +- { +- return total_over_dim_template< DComplexDblGDL> +- ( static_cast(p0), srcDim, sumDim-1, nan); +- } +- if( !doubleRes) +- { +- if( p0->Type() == GDL_FLOAT) +- { +- return total_over_dim_template< DFloatGDL> +- ( static_cast(p0), srcDim, sumDim-1, nan); +- } +- if( p0->Type() == GDL_COMPLEX) +- { +- return total_over_dim_template< DComplexGDL> +- ( static_cast(p0), srcDim, sumDim-1, nan); +- } +- // default for NOT /GDL_DOUBLE +- DFloatGDL* p0F = static_cast +- (p0->Convert2( GDL_FLOAT,BaseGDL::COPY)); +- auto_ptr p0F_guard( p0F); +- // p0F_guard.reset( p0F); +- return total_over_dim_template< DFloatGDL> +- ( p0F, srcDim, sumDim-1, false); +- } +- if( p0->Type() == GDL_COMPLEX) +- { +- DComplexDblGDL* p0D = static_cast +- (p0->Convert2( GDL_COMPLEXDBL,BaseGDL::COPY)); +- auto_ptr p0D_guard( p0D); +- // p0D_guard.reset( p0D); +- return total_over_dim_template< DComplexDblGDL> +- ( p0D, srcDim, sumDim-1, nan); +- } +- // default for /GDL_DOUBLE +- DDoubleGDL* p0D = static_cast +- (p0->Convert2( GDL_DOUBLE,BaseGDL::COPY)); +- auto_ptr p0D_guard( p0D); +- //p0D_guard.reset( p0D); +- return total_over_dim_template< DDoubleGDL>( p0D, srcDim, sumDim-1,nan); +- } +- else // cumulative +- { +- if (preserve) +- { +- switch (p0->Type()) +- { +- case GDL_BYTE: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); +- case GDL_INT: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); +- case GDL_UINT: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); +- case GDL_LONG: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); +- case GDL_ULONG: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); +- case GDL_LONG64: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); +- case GDL_ULONG64: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); +- case GDL_FLOAT: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nan); +- case GDL_DOUBLE: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nan); +- case GDL_COMPLEX: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nan); +- case GDL_COMPLEXDBL: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nan); +- default: assert(false); +- } +- } +- +- // INTEGER keyword takes precedence +- if( intRes ) +- { +- // We use GDL_LONG64 unless the input is GDL_ULONG64 +- if ( p0->Type() == GDL_LONG64 ) +- { +- return total_over_dim_cu_template +- ( static_cast(p0)->Dup(), sumDim-1, nan ); +- } +- if ( p0->Type() == GDL_ULONG64 ) +- { +- return total_over_dim_cu_template +- ( static_cast(p0)->Dup(), sumDim-1, nan ); +- } +- +- // Convert to Long64 +- return total_over_dim_cu_template +- ( static_cast +- (p0->Convert2( GDL_LONG64, BaseGDL::COPY)), sumDim-1, nan); +- +- } // integer results +- +- +- if( p0->Type() == GDL_DOUBLE) +- { +- return total_over_dim_cu_template< DDoubleGDL> +- ( static_cast(p0)->Dup(), sumDim-1, nan); +- } +- if( p0->Type() == GDL_COMPLEXDBL) +- { +- return total_over_dim_cu_template< DComplexDblGDL> +- ( static_cast(p0)->Dup(), sumDim-1, nan); +- } +- if( !doubleRes) +- { +- // special case for GDL_FLOAT has no advantage here +- if( p0->Type() == GDL_COMPLEX) +- { +- return total_over_dim_cu_template< DComplexGDL> +- ( static_cast(p0)->Dup(), sumDim-1, nan); +- } +- // default for NOT /GDL_DOUBLE +- return total_over_dim_cu_template< DFloatGDL> +- ( static_cast( p0->Convert2( GDL_FLOAT, +- BaseGDL::COPY)), sumDim-1, nan); +- } +- if( p0->Type() == GDL_COMPLEX) +- { +- return total_over_dim_cu_template< DComplexDblGDL> +- ( static_cast(p0->Convert2( GDL_COMPLEXDBL, +- BaseGDL::COPY)), sumDim-1, nan); +- } +- // default for /GDL_DOUBLE +- return total_over_dim_cu_template< DDoubleGDL> +- ( static_cast(p0->Convert2( GDL_DOUBLE, +- BaseGDL::COPY)), sumDim-1, nan); +- } +- } +- +- +- // passing 2nd argument by value is slightly better for float and double, +- // but incur some overhead for the complex class. +- template inline void MultOmitNaN(T& dest, T value) +- { +- if (isfinite(value)) +- { +-// #pragma omp atomic +- dest *= value; +- } +- } +- template inline void MultOmitNaNCpx(T& dest, T value) +- { +- dest *= T(isfinite(value.real())? value.real() : 1, +- isfinite(value.imag())? value.imag() : 1); +- } +- template<> inline void MultOmitNaN(DComplex& dest, DComplex value) +- { MultOmitNaNCpx(dest, value); } +- template<> inline void MultOmitNaN(DComplexDbl& dest, DComplexDbl value) +- { MultOmitNaNCpx(dest, value); } +- +- template inline void Nan2One(T& value) +- { if (!isfinite(value)) value = 1; } +- template inline void Nan2OneCpx(T& value) +- { +- value = T(isfinite(value.real())? value.real() : 1, +- isfinite(value.imag())? value.imag() : 1); +- } +- template<> inline void Nan2One(DComplex& value) +- { Nan2OneCpx< DComplex>(value); } +- template<> inline void Nan2One(DComplexDbl& value) +- { Nan2OneCpx< DComplexDbl>(value); } +- +- // product over all elements +- template +- BaseGDL* product_template( T* src, bool omitNaN) +- { +- typename T::Ty sum = 1; +- SizeT nEl = src->N_Elements(); +- if( !omitNaN) +- { +-TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared(sum) +-{ +-#pragma omp for reduction(*:sum) +- for ( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared(sum) +-{ +-#pragma omp for reduction(*:sum) +- for ( int i=0; i +- BaseGDL* product_template( DComplexGDL* src, bool omitNaN) +- { +- DComplexGDL::Ty sum = 1; +- SizeT nEl = src->N_Elements(); +- if( !omitNaN) +- { +- for ( SizeT i=0; i +- BaseGDL* product_template( DComplexDblGDL* src, bool omitNaN) +- { +- DComplexDblGDL::Ty sum = 1; +- SizeT nEl = src->N_Elements(); +- if( !omitNaN) +- { +- for ( SizeT i=0; i +- BaseGDL* product_cu_template( T* res, bool omitNaN) +- { +- SizeT nEl = res->N_Elements(); +- if( omitNaN) +- { +- for( SizeT i=0; i +- BaseGDL* product_over_dim_template( T* src, +- const dimension& srcDim, +- SizeT sumDimIx, +- bool omitNaN) +- { +- SizeT nEl = src->N_Elements(); +- +- // get dest dim and number of summations +- dimension destDim = srcDim; +- SizeT nSum = destDim.Remove( sumDimIx); +- +- T* res = new T( destDim, BaseGDL::NOZERO); +- +- // sumStride is also the number of linear src indexing +- SizeT sumStride = srcDim.Stride( sumDimIx); +- SizeT outerStride = srcDim.Stride( sumDimIx + 1); +- SizeT sumLimit = nSum * sumStride; +- SizeT rIx=0; +- for( SizeT o=0; o < nEl; o += outerStride) +- for( SizeT i=0; i < sumStride; ++i) +- { +- (*res)[ rIx] = 1; +- SizeT oi = o+i; +- SizeT oiLimit = sumLimit + oi; +- if( omitNaN) +- { +- for( SizeT s=oi; s +- BaseGDL* product_over_dim_cu_template( T* res, +- SizeT sumDimIx, +- bool omitNaN) +- { +- SizeT nEl = res->N_Elements(); +- const dimension& resDim = res->Dim(); +- if (omitNaN) +- { +- for( SizeT i=0; iNParam( 1); +- +- BaseGDL* p0 = e->GetParDefined( 0); +- +- SizeT nEl = p0->N_Elements(); +- if( nEl == 0) +- e->Throw( "Variable is undefined: "+e->GetParString(0)); +- +- if( p0->Type() == GDL_STRING) +- e->Throw( "String expression not allowed " +- "in this context: "+e->GetParString(0)); +- +- static int cumIx = e->KeywordIx( "CUMULATIVE"); +- static int nanIx = e->KeywordIx( "NAN"); +- static int intIx = e->KeywordIx("INTEGER"); +- static int preIx = e->KeywordIx("PRESERVE_TYPE"); +- bool KwCumul = e->KeywordSet( cumIx); +- bool KwNaN = e->KeywordSet( nanIx); +- bool KwInt = e->KeywordSet( intIx); +- bool KwPre = e->KeywordSet( preIx); +- bool nanInt=false; +- +- DLong sumDim = 0; +- if( nParam == 2) +- e->AssureLongScalarPar( 1, sumDim); +- +- if( sumDim == 0) { +- if( !KwCumul) { +- if (KwPre) +- { +- switch (p0->Type()) +- { +- case GDL_BYTE: return product_template(static_cast(p0), nanInt); +- case GDL_INT: return product_template(static_cast(p0), nanInt); +- case GDL_UINT: return product_template(static_cast(p0), nanInt); +- case GDL_LONG: return product_template(static_cast(p0), nanInt); +- case GDL_ULONG: return product_template(static_cast(p0), nanInt); +- case GDL_LONG64: return product_template(static_cast(p0), nanInt); +- case GDL_ULONG64: return product_template(static_cast(p0), nanInt); +- case GDL_FLOAT: return product_template(static_cast(p0), KwNaN); +- case GDL_DOUBLE: return product_template(static_cast(p0), KwNaN); +- case GDL_COMPLEX: return product_template(static_cast(p0), KwNaN); +- case GDL_COMPLEXDBL: return product_template(static_cast(p0), KwNaN); +- default: assert(false); +- } +- } +- +- // Integer parts derivated from Total code by Erin Sheldon +- // In IDL PRODUCT(), the INTEGER keyword takes precedence +- if (KwInt) { +- // We use GDL_LONG64 unless the input is GDL_ULONG64 +- if ((p0->Type() == GDL_LONG64) && (!KwNaN)) { +- return product_template +- ( static_cast(p0), nanInt ); +- } +- if ((p0->Type() == GDL_ULONG64) && (!KwNaN)) { +- return product_template +- (static_cast(p0), nanInt ); +- } +- +- // Convert to Long64 +- DLong64GDL* p0L64 = static_cast +- (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); +- auto_ptr guard( p0L64); +- if (KwNaN) { +- DFloatGDL* p0f = static_cast +- (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); +- auto_ptr guard( p0f); +- for( SizeT i=0; i( p0L64, nanInt); +- } // integer results +- +- if( p0->Type() == GDL_DOUBLE) { +- return product_template +- ( static_cast(p0), KwNaN); +- } +- if( p0->Type() == GDL_COMPLEXDBL) { +- return product_template +- ( static_cast(p0), KwNaN); +- } +- if( p0->Type() == GDL_COMPLEX) { +- DComplexDblGDL* p0D = static_cast +- (p0->Convert2( GDL_COMPLEXDBL,BaseGDL::COPY)); +- auto_ptr p0D_guard( p0D); +- //p0D_guard.reset( p0D); +- return product_template( p0D, KwNaN); +- } +- +- DDoubleGDL* p0D = static_cast +- (p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)); +- auto_ptr p0D_guard( p0D); +- // p0D_guard.reset( p0D); +- return product_template( p0D, KwNaN); +- } +- else +- { // KwCumul +- +- if (KwPre) +- { +- switch (p0->Type()) +- { +- case GDL_BYTE: return product_cu_template(static_cast(p0)->Dup(), nanInt); +- case GDL_INT: return product_cu_template(static_cast(p0)->Dup(), nanInt); +- case GDL_UINT: return product_cu_template(static_cast(p0)->Dup(), nanInt); +- case GDL_LONG: return product_cu_template(static_cast(p0)->Dup(), nanInt); +- case GDL_ULONG: return product_cu_template(static_cast(p0)->Dup(), nanInt); +- case GDL_LONG64: return product_cu_template(static_cast(p0)->Dup(), nanInt); +- case GDL_ULONG64: return product_cu_template(static_cast(p0)->Dup(), nanInt); +- case GDL_FLOAT: return product_cu_template(static_cast(p0)->Dup(), KwNaN); +- case GDL_DOUBLE: return product_cu_template(static_cast(p0)->Dup(), KwNaN); +- case GDL_COMPLEX: return product_cu_template(static_cast(p0)->Dup(), KwNaN); +- case GDL_COMPLEXDBL: return product_cu_template(static_cast(p0)->Dup(), KwNaN); +- default: assert(false); +- } +- } +- +- // Integer parts derivated from Total code by Erin Sheldon +- // In IDL PRODUCT(), the INTEGER keyword takes precedence +- if (KwInt) { +- // We use GDL_LONG64 unless the input is GDL_ULONG64 +- if ((p0->Type() == GDL_LONG64) && (!KwNaN)) { +- return product_cu_template +- ( static_cast(p0)->Dup(), nanInt); +- } +- if ((p0->Type() == GDL_ULONG64) && (!KwNaN)) { +- return product_cu_template +- ( static_cast(p0)->Dup(), nanInt); +- } +- // Convert to Long64 +- DLong64GDL* p0L64 = static_cast +- (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); +- auto_ptr guard( p0L64); +- if (KwNaN) { +- DFloatGDL* p0f = static_cast +- (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); +- auto_ptr guard( p0f); +- for( SizeT i=0; i +- ((p0L64)->Dup(), nanInt); +- } // integer results +- +- // special case as GDL_DOUBLE type overrides /GDL_DOUBLE +- if (p0->Type() == GDL_DOUBLE) { +- return product_cu_template< DDoubleGDL> +- ( static_cast(p0)->Dup(), KwNaN); +- } +- if (p0->Type() == GDL_COMPLEXDBL) { +- return product_cu_template< DComplexDblGDL> +- ( static_cast(p0)->Dup(), KwNaN); +- } +- if (p0->Type() == GDL_COMPLEX) { +- return product_cu_template< DComplexDblGDL> +- ( static_cast +- (p0->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY)), KwNaN); +- } +- return product_cu_template< DDoubleGDL> +- ( static_cast +- (p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)), KwNaN); +- } +- } +- +- // product over sumDim +- dimension srcDim = p0->Dim(); +- SizeT srcRank = srcDim.Rank(); +- +- if( sumDim < 1 || sumDim > srcRank) +- e->Throw( "Array must have "+i2s(sumDim)+ +- " dimensions: "+e->GetParString(0)); +- +- if (!KwCumul) { +- +- if (KwPre) +- { +- switch (p0->Type()) +- { +- case GDL_BYTE: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); +- case GDL_INT: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); +- case GDL_UINT: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); +- case GDL_LONG: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); +- case GDL_ULONG: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); +- case GDL_LONG64: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); +- case GDL_ULONG64: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); +- case GDL_FLOAT: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, KwNaN); +- case GDL_DOUBLE: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, KwNaN); +- case GDL_COMPLEX: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, KwNaN); +- case GDL_COMPLEXDBL: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, KwNaN); +- default: assert(false); +- } +- } +- +- // Integer parts derivated from Total code by Erin Sheldon +- // In IDL PRODUCT(), the INTEGER keyword takes precedence +- if (KwInt) { +- // We use GDL_LONG64 unless the input is GDL_ULONG64 +- if ((p0->Type() == GDL_LONG64 ) && (!KwNaN)) { +- return product_over_dim_template +- ( static_cast(p0), srcDim, sumDim-1, nanInt); +- } +- if ((p0->Type() == GDL_ULONG64) && (!KwNaN)) { +- return product_over_dim_template +- ( static_cast(p0), srcDim, sumDim-1, nanInt); +- } +- +- // Conver to Long64 +- DLong64GDL* p0L64 = static_cast +- (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); +- auto_ptr guard( p0L64); +- if (KwNaN) { +- DFloatGDL* p0f = static_cast +- (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); +- auto_ptr guard( p0f); +- for( SizeT i=0; i +- ( p0L64, srcDim, sumDim-1, nanInt); +- } // integer results +- +- if( p0->Type() == GDL_DOUBLE) { +- return product_over_dim_template< DDoubleGDL> +- ( static_cast(p0), srcDim, sumDim-1, KwNaN); +- } +- if( p0->Type() == GDL_COMPLEXDBL) { +- return product_over_dim_template< DComplexDblGDL> +- ( static_cast(p0), srcDim, sumDim-1, KwNaN); +- } +- if( p0->Type() == GDL_COMPLEX) { +- DComplexDblGDL* p0D = static_cast +- (p0->Convert2( GDL_COMPLEXDBL,BaseGDL::COPY)); +- auto_ptr p0D_guard( p0D); +- // p0D_guard.reset( p0D); +- return product_over_dim_template< DComplexDblGDL> +- ( p0D, srcDim, sumDim-1, KwNaN); +- } +- +- DDoubleGDL* p0D = static_cast +- (p0->Convert2( GDL_DOUBLE,BaseGDL::COPY)); +- auto_ptr p0D_guard( p0D); +- //p0D_guard.reset( p0D); +- return product_over_dim_template< DDoubleGDL> +- ( p0D, srcDim, sumDim-1,KwNaN); +- } +- else +- { // KwCumul +- +- if (KwPre) +- { +- switch (p0->Type()) +- { +- case GDL_BYTE: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); +- case GDL_INT: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); +- case GDL_UINT: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); +- case GDL_LONG: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); +- case GDL_ULONG: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); +- case GDL_LONG64: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); +- case GDL_ULONG64: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); +- case GDL_FLOAT: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, KwNaN); +- case GDL_DOUBLE: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, KwNaN); +- case GDL_COMPLEX: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, KwNaN); +- case GDL_COMPLEXDBL: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, KwNaN); +- default: assert(false); +- } +- } +- +- // Integer parts derivated from Total code by Erin Sheldon +- // In IDL PRODUCT(), the INTEGER keyword takes precedence +- if (KwInt) { +- // We use GDL_LONG64 unless the input is GDL_ULONG64 +- if ((p0->Type() == GDL_LONG64) && (!KwNaN)) { +- return product_over_dim_cu_template +- ( static_cast(p0)->Dup(), sumDim-1, nanInt); +- } +- if ((p0->Type() == GDL_ULONG64 ) && (!KwNaN)) { +- return product_over_dim_cu_template +- ( static_cast(p0)->Dup(), sumDim-1, nanInt); +- } +- +- // Convert to Long64 +- if (KwNaN) { +- DFloatGDL* p0f = static_cast +- (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); +- auto_ptr guard( p0f); +- for( SizeT i=0; i +- ( static_cast +- (p0f->Convert2( GDL_LONG64, BaseGDL::COPY)), sumDim-1, nanInt); +- } else { +- return product_over_dim_cu_template +- ( static_cast +- (p0->Convert2( GDL_LONG64, BaseGDL::COPY)), sumDim-1, nanInt); +- } +- } // integer results +- +- if( p0->Type() == GDL_DOUBLE) { +- return product_over_dim_cu_template< DDoubleGDL> +- ( static_cast(p0)->Dup(), sumDim-1, KwNaN); +- } +- if( p0->Type() == GDL_COMPLEXDBL) { +- return product_over_dim_cu_template< DComplexDblGDL> +- ( static_cast(p0)->Dup(), sumDim-1, KwNaN); +- } +- if( p0->Type() == GDL_COMPLEX) { +- return product_over_dim_cu_template< DComplexDblGDL> +- ( static_cast +- (p0->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY)), sumDim-1, KwNaN); +- } +- +- return product_over_dim_cu_template< DDoubleGDL> +- ( static_cast +- (p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)), sumDim-1, KwNaN); +- } +- } +- +- BaseGDL* array_equal( EnvT* e) +- { +- e->NParam( 2);//, "ARRAY_EQUAL"); +- +- BaseGDL* p0 = e->GetParDefined( 0);//, "ARRAY_EQUAL"); +- BaseGDL* p1 = e->GetParDefined( 1);//, "ARRAY_EQUAL"); +- +- if( p0 == p1) return new DByteGDL( 1); +- +- SizeT nEl0 = p0->N_Elements(); +- SizeT nEl1 = p1->N_Elements(); +- if( nEl0 != nEl1 && nEl0 != 1 && nEl1 != 1) +- return new DByteGDL( 0); +- +- auto_ptr p0_guard; +- auto_ptr p1_guard; +- if( p0->Type() != p1->Type()) +- { +- if( e->KeywordSet( 0)) // NO_TYPECONV +- return new DByteGDL( 0); +- else +- { +- DType aTy=p0->Type(); +- DType bTy=p1->Type(); +- if( DTypeOrder[aTy] >= DTypeOrder[bTy]) +- { +- p1 = p1->Convert2( aTy, BaseGDL::COPY); +- p1_guard.reset( p1); +- } +- else +- { +- p0 = p0->Convert2( bTy, BaseGDL::COPY); +- p0_guard.reset( p0); +- } +- } +- } +- +- if( p0->ArrayEqual( p1)) return new DByteGDL( 1); +- +- return new DByteGDL( 0); +- } +- +- BaseGDL* min_fun( EnvT* e) +- { +- SizeT nParam = e->NParam( 1); +- BaseGDL* searchArr = e->GetParDefined( 0); +- +- bool omitNaN = e->KeywordSet( "NAN"); +- +- static int subIx = e->KeywordIx("SUBSCRIPT_MAX"); +- bool subMax = e->KeywordPresent(subIx); +- +- static int dimIx = e->KeywordIx("DIMENSION"); +- bool dimSet = e->KeywordSet(dimIx); +- +- static int maxIx = e->KeywordIx("MAX"); +- bool maxSet = e->KeywordPresent(maxIx); +- +- DLong searchDim; +- if (dimSet) { +- e->AssureLongScalarKW(dimIx, searchDim); +- if (searchDim < 0 || searchDim > searchArr->Rank()) +- e->Throw("Illegal keyword value for DIMENSION"); +- } +- +- if (dimSet && searchArr->Rank() > 1) +- { +- searchDim -= 1; // user-supplied dimensions start with 1! +- +- // here destDim is in fact the srcDim... +- dimension destDim = searchArr->Dim(); +- SizeT searchStride = destDim.Stride(searchDim); +- SizeT outerStride = destDim.Stride(searchDim + 1); +- // ... and now becomes the destDim +- SizeT nSearch = destDim.Remove(searchDim); +- SizeT searchLimit = nSearch * searchStride; +- SizeT nEl = searchArr->N_Elements(); +- +- // memory allocation +- BaseGDL *maxVal, *resArr = searchArr->New(destDim, BaseGDL::NOZERO); +- DLongGDL *minElArr, *maxElArr; +- +- if (maxSet) +- { +- e->AssureGlobalKW(maxIx); // instead of using a guard pointer +- maxVal = searchArr->New(destDim, BaseGDL::NOZERO); +- } +- +- if (subMax) +- { +- e->AssureGlobalKW(subIx); // instead of using a guard pointer +- maxElArr = new DLongGDL(destDim); +- } +- +- if (nParam == 2) +- { +- e->AssureGlobalPar(1); // instead of using a guard pointer +- minElArr = new DLongGDL(destDim); +- } +- +- SizeT rIx = 0; +- for (SizeT o = 0; o < nEl; o += outerStride) for (SizeT i = 0; i < searchStride; ++i) +- { +- searchArr->MinMax( +- (nParam == 2 ? &((*minElArr)[rIx]) : NULL), +- (subMax ? &((*maxElArr)[rIx]) : NULL), +- &resArr, +- (maxSet ? &maxVal : NULL), +- omitNaN, o + i, searchLimit + o + i, searchStride, rIx +- ); +- rIx++; +- } +- +- if (nParam == 2) e->SetPar(1, minElArr); +- if (subMax) e->SetKW(subIx, maxElArr); +- if (maxSet) e->SetKW(maxIx, maxVal); +- +- return resArr; +- } +- else +- { +- DLong minEl; +- BaseGDL* res; +- +- if (maxSet) // MAX keyword given +- { +- e->AssureGlobalKW( 0); +- GDLDelete(e->GetKW( 0)); +- DLong maxEl; +- searchArr->MinMax( &minEl, &maxEl, &res, &e->GetKW( 0), omitNaN); +- if (subMax) e->SetKW(subIx, new DLongGDL(maxEl)); +- } +- else // no MAX keyword +- { +- if (subMax) +- { +- DLong maxEl; +- searchArr->MinMax( &minEl, &maxEl, &res, NULL, omitNaN); +- e->SetKW(subIx, new DLongGDL(maxEl)); +- } +- else searchArr->MinMax(&minEl, NULL, &res, NULL, omitNaN); +- } +- +- // handle index +- if (nParam == 2) e->SetPar(1, new DLongGDL( minEl)); +- else SysVar::SetC( minEl); +- return res; +- } +- } +- +- BaseGDL* max_fun( EnvT* e) +- { +- SizeT nParam = e->NParam( 1); +- BaseGDL* searchArr = e->GetParDefined( 0); +- +- bool omitNaN = e->KeywordSet( "NAN"); +- +- static int subIx = e->KeywordIx("SUBSCRIPT_MIN"); +- bool subMin = e->KeywordPresent(subIx); +- +- static int dimIx = e->KeywordIx("DIMENSION"); +- bool dimSet = e->KeywordSet(dimIx); +- +- static int minIx = e->KeywordIx("MIN"); +- bool minSet = e->KeywordPresent(minIx); +- +- DLong searchDim; +- if (dimSet) +- { +- e->AssureLongScalarKW(dimIx, searchDim); +- if (searchDim < 0 || searchDim > searchArr->Rank()) +- e->Throw("Illegal keyword value for DIMENSION"); +- } +- +- if (dimSet && searchArr->Rank() > 1) +- { +- searchDim -= 1; // user-supplied dimensions start with 1! +- +- // here destDim is in fact the srcDim... +- dimension destDim = searchArr->Dim(); +- SizeT searchStride = destDim.Stride(searchDim); +- SizeT outerStride = destDim.Stride(searchDim + 1); +- // ... and now becomes the destDim +- SizeT nSearch = destDim.Remove(searchDim); +- SizeT searchLimit = nSearch * searchStride; +- SizeT nEl = searchArr->N_Elements(); +- +- // memory allocation +- BaseGDL *minVal, *resArr = searchArr->New(destDim, BaseGDL::NOZERO); +- DLongGDL *minElArr, *maxElArr; +- +- if (minSet) +- { +- e->AssureGlobalKW(minIx); // instead of using a guard pointer +- minVal = searchArr->New(destDim, BaseGDL::NOZERO); +- } +- +- if (subMin) +- { +- e->AssureGlobalKW(subIx); // instead of using a guard pointer +- minElArr = new DLongGDL(destDim); +- } +- +- if (nParam == 2) +- { +- e->AssureGlobalPar(1); // instead of using a guard pointer +- maxElArr = new DLongGDL(destDim); +- } +- +- SizeT rIx = 0; +- for (SizeT o = 0; o < nEl; o += outerStride) for (SizeT i = 0; i < searchStride; ++i) +- { +- searchArr->MinMax( +- (subMin ? &((*minElArr)[rIx]) : NULL), +- (nParam == 2 ? &((*maxElArr)[rIx]) : NULL), +- (minSet ? &minVal : NULL), +- &resArr, +- omitNaN, o + i, searchLimit + o + i, searchStride, rIx +- ); +- rIx++; +- } +- +- if (nParam == 2) e->SetPar(1, maxElArr); +- if (subMin) e->SetKW(subIx, minElArr); +- if (minSet) e->SetKW(minIx, minVal); +- +- return resArr; +- } +- else +- { +- DLong maxEl; +- BaseGDL* res; +- +- if (minSet) // MIN keyword given +- { +- e->AssureGlobalKW( 0); +- GDLDelete(e->GetKW( 0)); +- DLong minEl; +- searchArr->MinMax( &minEl, &maxEl, &e->GetKW( 0), &res, omitNaN); +- if (subMin) e->SetKW(subIx, new DLongGDL(minEl)); +- } +- else // no MIN keyword +- { +- if (subMin) +- { +- DLong minEl; +- searchArr->MinMax( &minEl, &maxEl, NULL, &res, omitNaN); +- e->SetKW(subIx, new DLongGDL(minEl)); +- } +- else searchArr->MinMax(NULL, &maxEl, NULL, &res, omitNaN); +- } +- +- // handle index +- if (nParam == 2) e->SetPar(1, new DLongGDL( maxEl)); +- else SysVar::SetC(maxEl); +- return res; +- } +- } +- +-BaseGDL* transpose( EnvT* e) +- { +- SizeT nParam=e->NParam( 1); +- +- BaseGDL* p0 = e->GetParDefined( 0); +- if( p0->Type() == GDL_STRUCT) +- e->Throw("Struct expression not allowed in this context: "+ +- e->GetParString(0)); +- +- SizeT rank = p0->Rank(); +- if( rank == 0) +- e->Throw( "Expression must be an array " +- "in this context: "+ e->GetParString(0)); +- +- if( nParam == 2) +- { +- +- BaseGDL* p1 = e->GetParDefined( 1); +- if( p1->N_Elements() != rank) +- e->Throw("Incorrect number of elements in permutation."); +- +- DUInt* perm = new DUInt[rank]; +- auto_ptr perm_guard( perm); +- +- DUIntGDL* p1L = static_cast +- (p1->Convert2( GDL_UINT, BaseGDL::COPY)); +- for( SizeT i=0; iThrow( "Incorrect permutation vector."); +- } +- return p0->Transpose( perm); +- } +- +- return p0->Transpose( NULL); +- } +- +- +-// BaseGDL* matrix_multiply( EnvT* e) +-// { +-// SizeT nParam=e->NParam( 2); +-// +-// BaseGDL* a = e->GetNumericArrayParDefined( 0); +-// BaseGDL* b = e->GetNumericArrayParDefined( 1); +-// +-// static int aTIx = e->KeywordIx("ATRANSPOSE"); +-// bool aT = e->KeywordPresent(aTIx); +-// static int bTIx = e->KeywordIx("BTRANSPOSE"); +-// bool bT = e->KeywordPresent(bTIx); +-// +-// static int strassenIx = e->KeywordIx("STRASSEN_ALGORITHM"); +-// bool strassen = e->KeywordPresent(strassenIx); +-// +-// +-// if( p1->N_Elements() != rank) +-// e->Throw("Incorrect number of elements in permutation."); +-// +-// DUInt* perm = new DUInt[rank]; +-// auto_ptr perm_guard( perm); +-// +-// DUIntGDL* p1L = static_cast +-// (p1->Convert2( GDL_UINT, BaseGDL::COPY)); +-// for( SizeT i=0; iThrow( "Incorrect permutation vector."); +-// } +-// return p0->Transpose( perm); +-// } +-// +-// return a->Transpose( NULL); +-// } +- +- // helper function for sort_fun, recursive +- // optimized version +- template< typename IndexT> +- void MergeSortOpt( BaseGDL* p0, IndexT* hhS, IndexT* h1, IndexT* h2, +- SizeT len) +- { +- if( len <= 1) return; +- +- SizeT h1N = len / 2; +- SizeT h2N = len - h1N; +- +- // 1st half +- MergeSortOpt(p0, hhS, h1, h2, h1N); +- +- // 2nd half +- IndexT* hhM = &hhS[h1N]; +- MergeSortOpt(p0, hhM, h1, h2, h2N); +- +- SizeT i; +- for(i=0; iGreater( h1[h1Ix], h2[h2Ix])) +- hhS[ i] = h2[ h2Ix++]; +- else +- hhS[ i] = h1[ h1Ix++]; +- } +- for(; h1Ix < h1N; ++i) hhS[ i] = h1[ h1Ix++]; +- for(; h2Ix < h2N; ++i) hhS[ i] = h2[ h2Ix++]; +- } +- +- // helper function for sort_fun, recursive +- void MergeSort( BaseGDL* p0, SizeT* hh, SizeT* h1, SizeT* h2, +- SizeT start, SizeT end) +- { +- if( start+1 >= end) return; +- +- SizeT middle = (start+end) / 2; +- +- MergeSort(p0, hh, h1, h2, start, middle); +- MergeSort(p0, hh, h1, h2, middle, end); +- +- SizeT h1N = middle - start; +- SizeT h2N = end - middle; +- +- SizeT* hhS = &hh[start]; +- +- SizeT i; +- for(i=0; iGreater( h1[h1Ix], h2[h2Ix])) +- hhS[ i] = h2[ h2Ix++]; +- else +- hhS[ i] = h1[ h1Ix++]; +- } +- for(; h1Ix < h1N; ++i) hhS[ i] = h1[ h1Ix++]; +- for(; h2Ix < h2N; ++i) hhS[ i] = h2[ h2Ix++]; +- } +- +- // sort function uses MergeSort +- BaseGDL* sort_fun( EnvT* e) +- { +- e->NParam( 1); +- +- BaseGDL* p0 = e->GetParDefined( 0); +- +- if( p0->Type() == GDL_STRUCT) +- e->Throw( "Struct expression not allowed in this context: "+ +- e->GetParString(0)); +- +- static int l64Ix = e->KeywordIx( "L64"); +- bool l64 = e->KeywordSet( l64Ix); +- +- SizeT nEl = p0->N_Elements(); +- +- // helper arrays +- DLongGDL* res = new DLongGDL( dimension( nEl), BaseGDL::INDGEN); +- +- DLong nanIx = nEl; +- if( p0->Type() == GDL_FLOAT) +- { +- DFloatGDL* p0F = static_cast(p0); +- for( DLong i=nEl-1; i >= 0; --i) +- { +- if( isnan((*p0F)[ i]) )//|| !isfinite((*p0F)[ i])) +- { +- --nanIx; +- (*res)[i] = (*res)[nanIx]; +- (*res)[ nanIx] = i; +- +-// cout << "swap " << i << " with " << nanIx << endl; +-// cout << "now: "; +-// for( DLong ii=0; ii < nEl; ++ii) +-// { +-// cout << (*res)[ii] << " "; +-// } +-// cout << endl; +- } +- } +- } +- else if( p0->Type() == GDL_DOUBLE) +- { +- DDoubleGDL* p0F = static_cast(p0); +- for( DLong i=nEl-1; i >= 0; --i) +- { +- if( isnan((*p0F)[ i]))// || !isfinite((*p0F)[ i])) +- { +- --nanIx; +- (*res)[i] = (*res)[nanIx]; +- (*res)[ nanIx] = i; +- } +- } +- } +- else if( p0->Type() == GDL_COMPLEX) +- { +- DComplexGDL* p0F = static_cast(p0); +- for( DLong i=nEl-1; i >= 0; --i) +- { +- if( isnan((*p0F)[ i].real()) || //!isfinite((*p0F)[ i].real()) || +- isnan((*p0F)[ i].imag()))// || !isfinite((*p0F)[ i].imag()) ) +- { +- --nanIx; +- (*res)[i] = (*res)[nanIx]; +- (*res)[ nanIx] = i; +- } +- } +- } +- else if( p0->Type() == GDL_COMPLEXDBL) +- { +- DComplexDblGDL* p0F = static_cast(p0); +- for( DLong i=nEl-1; i >= 0; --i) +- { +- if( isnan((*p0F)[ i].real()) || //!isfinite((*p0F)[ i].real()) || +- isnan((*p0F)[ i].imag()))// || !isfinite((*p0F)[ i].imag()) ) +- { +- --nanIx; +- (*res)[i] = (*res)[nanIx]; +- (*res)[ nanIx] = i; +- } +- } +- } +- +-// cout << "nEl " << nEl << " nanIx " << nanIx << endl; +- nEl = nanIx; +-// cout << "sorting: "; +-// for( DLong ii=0; ii < nEl; ++ii) +-// { +-// cout << (*res)[ii] << " "; +-// } +-// cout << endl; +- +- DLong *hh = static_cast(res->DataAddr()); +- +- DLong* h1 = new DLong[ nEl/2]; +- DLong* h2 = new DLong[ (nEl+1)/2]; +- // call the sort routine +- MergeSortOpt( p0, hh, h1, h2, nEl); +- delete[] h1; +- delete[] h2; +- +- if( l64) +- { +- // leave it this way, as sorting of more than 2^31 +- // items seems not feasible in the future we might +- // use MergeSortOpt(...) for this +- return res->Convert2( GDL_LONG64); +- } +- +- return res; +- } +- +- // uses MergeSort +- // 2 parts in the code: without "width" or with "width" (limited to 1D and 2D) +- BaseGDL* median( EnvT* e) { +- +- BaseGDL* p0 = e->GetParDefined( 0); +- +- if( p0->Type() == GDL_PTR) +- e->Throw( "Pointer expression not allowed in this context: "+ e->GetParString(0)); +- if( p0->Type() == GDL_OBJ) +- e->Throw( "Object expression not allowed in this context: "+ e->GetParString(0)); +- if( p0->Type() == GDL_STRUCT) +- e->Throw( "Struct expression not allowed in this context: "+ e->GetParString(0)); +- +- if( p0->Rank() == 0) +- e->Throw( "Expression must be an array in this context: "+ e->GetParString(0)); +- +- SizeT nParam = e->NParam( 1); +- SizeT nEl = p0->N_Elements(); +- +- // "f_nan" and "d_nan" used by both parts ... +- static DStructGDL *Values = SysVar::Values(); +- DFloat f_nan=(*static_cast(Values->GetTag(Values->Desc()->TagIndex("F_NAN"), 0)))[0]; +- DDouble d_nan=(*static_cast(Values->GetTag(Values->Desc()->TagIndex("D_NAN"), 0)))[0]; +- +- // -------------------------------------------------------- +- // begin of the part 1: without "width" param +- if( nParam == 1) { +- +- static int evenIx = e->KeywordIx( "EVEN"); +- +- // TYPE +- bool dbl = +- p0->Type() == GDL_DOUBLE || +- p0->Type() == GDL_COMPLEXDBL || +- e->KeywordSet(e->KeywordIx("DOUBLE")); +- DType type = dbl ? GDL_DOUBLE : GDL_FLOAT; +- bool noconv = (dbl && p0->Type() == GDL_DOUBLE) || +- (!dbl && p0->Type() == GDL_FLOAT); +- +- // DIMENSION keyword +- DLong dim = 0; +- DLong nmed = 1; +- BaseGDL *res; +- e->AssureLongScalarKWIfPresent( "DIMENSION", dim); +- +- // cout << "dim : "<< dim << endl; +- +- if (dim > p0->Rank()) +- e->Throw( "Illegal keyword value for DIMENSION."); +- +- if (dim > 0) { +- DLong dims[8]; +- DLong k = 0; +- for (SizeT i=0; iRank(); ++i) +- if (i != (dim-1)) { +- nmed *= p0->Dim(i); +- dims[k++] = p0->Dim(i); +- } +- dimension dimRes((DLong *) dims, p0->Rank()-1); +- res = dbl +- ? static_cast(new DDoubleGDL(dimRes, BaseGDL::NOZERO)) +- : static_cast(new DFloatGDL(dimRes, BaseGDL::NOZERO)); +- } else { +- res = dbl +- ? static_cast(new DDoubleGDL(1)) +- : static_cast(new DFloatGDL(1)); +- } +- +- // conversion of Complex types +- if (p0->Type() == GDL_COMPLEX) p0 = p0->Convert2(GDL_FLOAT, BaseGDL::COPY); +- if (p0->Type() == GDL_COMPLEXDBL) p0 = p0->Convert2(GDL_DOUBLE, BaseGDL::COPY); +- +- // helper arrays +- if (nmed > 1) nEl = p0->N_Elements() / nmed; +- +- // cout << "hello2" << endl; +- +- DLong *hh = new DLong[ nEl]; +- DLong* h1 = new DLong[ nEl/2]; +- DLong* h2 = new DLong[ (nEl+1)/2]; +- +- DLong accumStride = 1; +- if (nmed > 1) +- for( DLong i=0; iDim(i); +- +- BaseGDL *op1, *op2, *op3; +- if (dbl) op3 = new DDoubleGDL(2); +- else op3 = new DFloatGDL(2); +- +- // nEl_extern is used to store "nEl" initial value +- DLong nanIx, nEl_extern; +- nEl_extern=nEl; +- // if (nmed > 1) nEl_extern = p0->N_Elements() / nmed; +- //else nEl_extern = p0->N_Elements(); +- +- // cout << "hello type" << p0->Type() << endl; +- +- // Loop over all subarray medians +- for (SizeT k=0; kType() == GDL_DOUBLE) { +- DDoubleGDL* p0F = static_cast(p0); +- for( DLong i=nEl-1; i >= 0; --i) { +- if( isnan((*p0F)[i])) { +- --nanIx; +- hh[i] = hh[nanIx]; +- hh[ nanIx] = i; +- } +- } +- } +- +- if (p0->Type() == GDL_FLOAT) { +- DFloatGDL* p0F = static_cast(p0); +- for( DLong i=nEl-1; i >= 0; --i) { +- if( isnan((*p0F)[i])) { +- --nanIx; +- hh[i] = hh[nanIx]; +- hh[ nanIx] = i; +- } +- } +- } +- +- //cout << "nEl " << nEl << " nanIx " << nanIx << endl; +- nEl = nanIx; +- } +- else +- { +- nanIx = nEl; +- nEl=nEl_extern; +- +- // DLong nanIx = nEl; +- // Starting Element +- DLong start = accumStride * p0->Dim(dim-1) * (k / accumStride) + +- (k % accumStride); +- for( DLong i=0; iType() == GDL_FLOAT) { +- DFloatGDL* p0F = static_cast(p0); +- for( DLong i=nEl-1; i >= 0; --i) { +- jj=start + i * accumStride; +- if( isnan((*p0F)[ jj]) ) { +- --nanIx; +- hh[i] = hh[nanIx]; +- hh[ nanIx] = i; +- } +- } +- nEl = nanIx; +- } +- +- if (p0->Type() == GDL_DOUBLE) { +- DDoubleGDL* p0F = static_cast(p0); +- for( DLong i=nEl-1; i >= 0; --i) { +- jj=start + i * accumStride; +- if( isnan((*p0F)[ jj]) ) { +- --nanIx; +- hh[i] = hh[nanIx]; +- hh[ nanIx] = i; +- } +- } +- //cout << "nanIx :" << nanIx << "nEl :" << nEl << endl; +- nEl = nanIx; +- } +- } +- DLong medEl, medEl_1; +- +- // call the sort routine +- if (nEl > 1) { +- MergeSortOpt( p0, hh, h1, h2, nEl); +- medEl = hh[ nEl/2]; +- medEl_1 = hh[ nEl/2 - 1]; +- } else { +- if (nEl == 1) { +- medEl = hh[0]; +- medEl_1 = hh[0]; +- } else +- { // normal case, more than one element, nothing to do +- //cout << "gasp : no result ! " << endl; +- } +- } +- +- if (nEl <= 0) { // we have a NaN +- if (dbl) (*static_cast(res))[k] = d_nan; +- else (*static_cast(res))[k] = f_nan; +- } else { +- //cout << k << "" << (*static_cast(p0))[medEl] << " " +- // << (*static_cast(p0))[medEl_1] << endl; +- //cout << "k :" << k << endl; +- if( (nEl % 2) == 1 || !e->KeywordSet( evenIx)) { +- if (nmed == 1) +- res = p0->NewIx(medEl)->Convert2(type, BaseGDL::CONVERT); +- else { +- if (noconv) +- { +- if (dbl) (*static_cast(res))[k] = (*static_cast(p0))[medEl]; +- else (*static_cast(res))[k] = (*static_cast(p0))[medEl]; +- } +- else +- { +- op1 = p0->NewIx(medEl)->Convert2(type, BaseGDL::CONVERT); +- if (dbl) (*static_cast(res))[k] = (*static_cast(op1))[0]; +- else (*static_cast(res))[k] = (*static_cast(op1))[0]; +- delete(op1); +- } +- } +- } else { +- if (noconv) +- { +- if (dbl) (*static_cast(res))[k] = .5 * ( +- (*static_cast(p0))[medEl] + +- (*static_cast(p0))[medEl_1] +- ); +- else (*static_cast(res))[k] = .5 * ( +- (*static_cast(p0))[medEl] + +- (*static_cast(p0))[medEl_1] +- ); +- } +- else +- { +- op1 = p0->NewIx(medEl)->Convert2(type, BaseGDL::CONVERT); +- op2 = p0->NewIx(medEl_1)->Convert2(type, BaseGDL::CONVERT); +- if (nmed == 1) res = op2->Add(op1)->Div(op3); // TODO: leak with res? +- else +- { +- if (dbl) (*static_cast(res))[k] = +- (*static_cast((op2->Add(op1)->Div(op3))))[0]; +- else (*static_cast(res))[k] = +- (*static_cast((op2->Add(op1)->Div(op3))))[0]; +- delete(op2); +- } +- delete(op1); +- } +- } +- } +- } +- delete(op3); +- delete[] h1; +- delete[] h2; +- delete[] hh; +- +- return res; +- } +- +- // begin of the part 2: with "width" param +- if( nParam == 2) { +- // with parameter Width : median filtering with no optimisation, +- // such as histogram algorithms. +- // Copyright: (C) 2008 by Nicolas Galmiche +- +- // basic checks on "vector/array" input +- DDoubleGDL* p0 = e->GetParAs( 0); +- +- if( p0->Rank() > 2) +- e->Throw( "Only 1 or 2 dimensions allowed: "+ e->GetParString(0)); +- +- // basic checks on "width" input +- DDoubleGDL* p1d = e->GetParAs(1); +- +- if (p1d->N_Elements() > 1 || (*p1d)[0] <=0 ) +- e->Throw( "Width must be a positive scalar or 1 (positive) element array in this context: "+ e->GetParString(0)); +- DLong MaxAllowedWidth=0; +- if (p0->Rank() == 1) MaxAllowedWidth=p0->N_Elements(); +- if (p0->Rank() == 2) { +- MaxAllowedWidth=p0->Dim(0); +- if (p0->Dim(1) < MaxAllowedWidth) MaxAllowedWidth=p0->Dim(1); +- } +- const int debug =0; +- if (debug == 1) { +- cout << "X dim " << p0->Dim(0) <Dim(1) <Throw("Width must be > 1, and < dimension of array (NaN or Inf)"); +- +- DLongGDL* p1 = e->GetParAs(1); +- +- DDoubleGDL *tamp = new DDoubleGDL(p0->Dim(),BaseGDL::NOZERO); +- DDouble min=((*p0)[0]); +- DDouble max=min; +- +- for (SizeT ii=0 ; iiN_Elements() ; ++ii) +- {(*tamp)[ii]=(*p0)[ii]; +- if ( (*p0)[ii] < min ) min = ((*p0)[ii]); +- if ( (*p0)[ii] > max ) max = ((*p0)[ii]); +- } +- +- //---------------------------- END d'acquisistion des paramètres ------------------------------------- +- +- +- static int evenIx = e->KeywordIx( "EVEN"); +- static int doubleIx = e->KeywordIx( "DOUBLE"); +- static DStructGDL *Values = SysVar::Values(); +- DDouble d_nan=(*static_cast(Values->GetTag(Values->Desc()->TagIndex("D_NAN"), 0)))[0]; +- DDouble d_infinity= (*static_cast(Values->GetTag(Values->Desc()->TagIndex("D_INFINITY"), 0)))[0]; +- +- //------------------------------ Init variables and allocation --------------------------------------- +- SizeT width=(*p1)[0]; +- SizeT N_MaskElem= width*width; +- SizeT larg = p0->Stride(1); +- SizeT haut = p0->Stride(2)/larg; +- SizeT lim= static_cast(round(width/2)); +- SizeT init=(lim*larg+lim); +- +- // we don't go further if dimension(s) versus not width OK +- +- if (debug == 1) {cout << "ici" <Rank() == 1) { +- if (larg < width || width==1 ) e->Throw( "Width must be > 1, and < width of vector"); +- } +- if ( p0->Rank() == 2) { +- if (larg < width || haut < width || width==1) e->Throw("Width must be > 1, and < dimension of array"); +- } +- +- // for 2D arrays, we use the algorithm described in paper +- // from T. Huang, G. Yang, and G. Tang, “A Fast Two-Dimensional Median +- // Filtering Algorithm,” IEEE Trans. Acoust., Speech, Signal Processing, +- // vol. 27, no. 1, pp. 13–18, 1979. +- +- if ( (e->GetParDefined( 0)->Type() == GDL_BYTE || +- e->GetParDefined( 0)->Type() == GDL_INT || +- e->GetParDefined( 0)->Type() == GDL_UINT || +- e->GetParDefined( 0)->Type() == GDL_LONG || +- e->GetParDefined( 0)->Type() == GDL_ULONG || +- e->GetParDefined( 0)->Type() == GDL_LONG64 || +- e->GetParDefined( 0)->Type() == GDL_ULONG64) && +- (haut>1)) +- { +- SizeT taille=static_cast(abs(max)-min+1); +- DDoubleGDL* Histo = new DDoubleGDL(taille,BaseGDL::NOZERO); +- if (width % 2 ==0) +- { +- for(SizeT i=0 ; i((*p0)[ii+yy*larg]-min)]++; +- } +- +- while (ltmed+(*Histo)[med]<=(N_MaskElem /2)) +- { +- ltmed+= static_cast((*Histo)[med]); +- ++med; +- } +- if (e->KeywordSet( evenIx)) +- { +- +- SizeT EvenMed=med; +- //if ((*Histo)[EvenMed]==1 || (ltmed!=0 && ltmed !=(N_MaskElem /2) -1)) +- if ((*Histo)[EvenMed]==1 || (ltmed!=0 && N_MaskElem /2- ltmed!=1) ) +- { +- while ((*Histo)[EvenMed-1]==0) +- { EvenMed--;} +- (*tamp)[init+i*larg]=((med+min)+(EvenMed-1+min))/2; +- } +- else +- (*tamp)[init+i*larg]=med+min; +- } +- else +- {(*tamp)[init+i*larg]=med+min; } +- +- for(SizeT j=init+i*larg +1; j((*p0)[initMask-1+k*larg]-min)]--; +- if ((*p0)[initMask-1+k*larg]-min((*p0)[initMask+k*larg+2*lim-1]-min)]++; +- if ((*p0)[initMask+k*larg+2*lim-1]-minN_MaskElem /2) +- { +- while(ltmed>N_MaskElem /2) +- { +- --med; +- ltmed-=static_cast((*Histo)[med]); +- } +- } +- else +- { +- while (ltmed+(*Histo)[med]<=(N_MaskElem /2)) +- { +- ltmed+= static_cast((*Histo)[med]); +- ++med; +- } +- } +- +- if (e->KeywordSet( evenIx)) +- { +- SizeT EvenMed=med; +- if ((*Histo)[EvenMed]==1 || (ltmed!=0 &&N_MaskElem /2- ltmed!=1 )) +- { +- while ((*Histo)[EvenMed-1]==0) +- { EvenMed--;} +- (*tamp)[j]=((med+min)+(EvenMed-1+min))/2; +- } +- else +- {(*tamp)[j]=med+min; } +- } +- else +- {(*tamp)[j]=med+min; } +- } +- } +- } +- else +- { +- for(SizeT i=0 ; i((*p0)[ii+yy*larg]-min)]++; +- } +- +- while (ltmed+(*Histo)[med]<=(N_MaskElem /2)) +- { +- ltmed+= static_cast((*Histo)[med]); +- ++med; +- } +- (*tamp)[init+i*larg]=med+min; +- +- for(SizeT j=init+i*larg +1; j((*p0)[initMask-1+k*larg]-min)]--; +- if ((*p0)[initMask-1+k*larg]-min((*p0)[initMask+k*larg+2*lim]-min)]++; +- if ((*p0)[initMask+k*larg+2*lim]-minN_MaskElem /2) +- { +- while(ltmed>N_MaskElem /2) +- { +- --med; +- ltmed-=static_cast((*Histo)[med]); +- } +- } +- else +- { +- while (ltmed+(*Histo)[med]<=(N_MaskElem /2)) +- { +- ltmed+= static_cast((*Histo)[med]); +- ++med; +- } +- } +- +- (*tamp)[j]=med+min; +- +- } +- } +- } +- +- } +- else +- { +- DLong* hh; +- DLong* h1; +- DLong* h2; +- DDoubleGDL* Mask,*Mask1D; +- if ( p0->Rank() != 1 ) +- { +- hh = new DLong[ N_MaskElem]; +- h1 = new DLong[ N_MaskElem/2]; +- h2= new DLong[ (N_MaskElem+1)/2]; +- Mask = new DDoubleGDL(N_MaskElem,BaseGDL::NOZERO); +- +- for( DLong i=0; iRank() == 1 )//------------------------ For a vector with even width ------------------- +- { +- for (SizeT col= lim ; col(Mask1Dbis); +- MergeSortOpt( besort, hhbis, h1bis, h2bis,(width - ctl_NaN)); +- if (e->KeywordSet( evenIx)&& (width - ctl_NaN) % 2 == 0) +- (*tamp)[col]=((*Mask1Dbis)[hhbis[ (width-ctl_NaN)/2]]+(*Mask1Dbis +- )[hhbis [ (width - ctl_NaN-1)/2]])/2; +- else +- (*tamp)[col]=(*Mask1Dbis)[hhbis[ (width- ctl_NaN)/2]]; +- delete[]hhbis; +- delete[]h2bis; +- delete[]h1bis; +- } +- } +- else +- { +- BaseGDL* besort=static_cast(Mask1D); +- MergeSortOpt( besort, hh, h1, h2,width ); // call the sort routine +- +- if (e->KeywordSet( evenIx)) +- +- (*tamp)[col]=((*Mask1D)[hh[ width/2]]+(*Mask1D)[hh[ (width-1)/2]])/2; +- else +- (*tamp)[col]=(*Mask1D)[hh[ width/2]];// replace value by Mask median +- } +- } +- +- } +- else//------------------------ For an array with even width ------------------- +- { +- SizeT jj; +- for(SizeT i=0 ; i(Maskb); +- MergeSortOpt( besort, hhb, h1b, h2b,(N_MaskElem - ctl_NaN)); +- if ((N_MaskElem - ctl_NaN) % 2 == 0 && e->KeywordSet( evenIx)) +- (*tamp)[j]=((*Maskb)[hhb[ (N_MaskElem-ctl_NaN)/2]]+(*Maskb)[hhb +- [ (N_MaskElem - +- ctl_NaN-1)/2]])/2; +- else +- (*tamp)[j]=(*Maskb)[hhb[ (N_MaskElem- ctl_NaN)/2]]; +- delete[]hhb; +- delete[]h2b; +- delete[]h1b; +- } +- } +- else +- { +- BaseGDL* besort=static_cast(Mask); +- MergeSortOpt( besort, hh, h1, h2, N_MaskElem); // call the sort routine +- if (e->KeywordSet( evenIx)) +- (*tamp)[j]=((*Mask)[hh[ N_MaskElem/2]]+(*Mask)[hh[ (N_MaskElem-1)/2]])/2; +- else +- (*tamp)[j]=(*Mask)[hh[ N_MaskElem/2]];// replace value by median Mask one +- } +- } +- } +- } +- } +- +- else +- { +- if ( p0->Rank() == 1 )//------------------------ For a vector with odd width ------------------- +- +- { +- for (SizeT col= lim ; col(Mask1Dbis); +- MergeSortOpt( besort, hhbis, h1bis, h2bis,(width - ctl_NaN)); +- if (e->KeywordSet( evenIx)&& (width - ctl_NaN) % 2 == 0) +- (*tamp)[col]=((*Mask1Dbis)[hhbis[ (width-ctl_NaN)/2]]+(*Mask1Dbis +- )[hhbis [ (width - ctl_NaN-1)/2]])/2; +- else(*tamp)[col]=(*Mask1Dbis)[hhbis[ (width- ctl_NaN)/2]]; +- delete[]hhbis; +- delete[]h2bis; +- delete[]h1bis; +- } +- } +- else +- { +- BaseGDL* besort=static_cast(Mask1D); +- MergeSortOpt( besort, hh, h1, h2,width ); // call the sort routine +- (*tamp)[col]=(*Mask1D)[hh[ (width)/2]]; // replace value by Mask median +- } +- } +- +- } +- +- else //----------------------------- For an array with odd width --------------------------------- +- { +- SizeT jj; +- for(SizeT i=0 ; i(Maskb); +- MergeSortOpt( besort, hhb, h1b, h2b,(N_MaskElem - ctl_NaN)); +- if ((N_MaskElem - ctl_NaN) % 2 == 0 && e->KeywordSet( evenIx)) +- (*tamp)[j]=((*Maskb)[hhb[ (N_MaskElem-ctl_NaN)/2]]+(*Maskb)[hhb +- [ (N_MaskElem - +- ctl_NaN-1)/2]])/2; +- else(*tamp)[j]=(*Maskb)[hhb[(N_MaskElem- ctl_NaN)/2]]; +- delete[]hhb; +- delete[]h2b; +- delete[]h1b; +- } +- } +- else +- { +- BaseGDL* besort=static_cast(Mask); +- MergeSortOpt( besort, hh, h1, h2, N_MaskElem); // call the sort routine +- (*tamp)[j]=(*Mask)[hh[ (N_MaskElem)/2]]; // replace value by Mask median +- } +- } +- } +- } +- } +- +- //--------------------------- END OF MEDIAN FILTER ALOGORITHMS ----------------------------------- +- +- delete[] h1; +- delete[] h2; +- delete[] hh; +- } +- if ( e->GetParDefined( 0)->Type() == GDL_DOUBLE || p0->Type() == GDL_COMPLEXDBL ||e->KeywordSet( doubleIx) ) +- return tamp; +- else if (e->GetParDefined( 0)->Type() == GDL_BYTE) +- return tamp->Convert2(GDL_BYTE,BaseGDL::CONVERT); +- +- return tamp->Convert2(GDL_FLOAT,BaseGDL::CONVERT); +- +- }// end if +- +- }// end of median +- +- BaseGDL* shift_fun( EnvT* e) +- { +- SizeT nParam = e->NParam( 2); +- +- BaseGDL* p0 = e->GetParDefined( 0); +- +- SizeT nShift = nParam - 1; +- if( nShift == 1) +- { +- DLong s1; +- e->AssureLongScalarPar( 1, s1); +- +- // IncRef[Obj] done for GDL_PTR and GDL_OBJ +- return p0->CShift( s1); +- } +- +- if( p0->Rank() != nShift) +- e->Throw( "Incorrect number of arguments."); +- +- DLong sIx[ MAXRANK]; +- for( SizeT i=0; i< nShift; i++) +- e->AssureLongScalarPar( i+1, sIx[ i]); +- +- if( p0->Type() == GDL_OBJ) +- GDLInterpreter::IncRefObj( static_cast(p0)); +- else if( p0->Type() == GDL_PTR) +- GDLInterpreter::IncRef( static_cast(p0)); +- +- return p0->CShift( sIx); +- } +- +- BaseGDL* arg_present( EnvT* e) +- { +- e->NParam( 1); +- +- if( !e->GlobalPar( 0)) +- return new DIntGDL( 0); +- +- EnvBaseT* caller = e->Caller(); +- if( caller == NULL) +- return new DIntGDL( 0); +- +- BaseGDL** pp0 = &e->GetPar( 0); +- +- int ix = caller->FindGlobalKW( pp0); +- if( ix == -1) +- return new DIntGDL( 0); +- +- return new DIntGDL( 1); +- } +- +- BaseGDL* eof_fun( EnvT* e) +- { +- e->NParam( 1); +- +- DLong lun; +- e->AssureLongScalarPar( 0, lun); +- +- bool stdLun = check_lun( e, lun); +- if( stdLun) +- return new DIntGDL( 0); +- +- // nicer error message (Disregard if socket) +- if ( fileUnits[ lun-1].SockNum() == -1) { +- if( !fileUnits[ lun-1].IsOpen()) +- throw GDLIOException( e->CallingNode(), "File unit is not open: "+i2s( lun)+"."); +- +- if( fileUnits[ lun-1].Eof()) +- return new DIntGDL( 1); +- } else { +- // Socket +- string *recvBuf = &fileUnits[ lun-1].RecvBuf(); +- if (recvBuf->size() == 0) +- return new DIntGDL( 1); +- } +- return new DIntGDL( 0); +- } +- +- BaseGDL* convol( EnvT* e) +- { +- SizeT nParam=e->NParam( 2); +- +- BaseGDL* p0 = e->GetNumericParDefined( 0); +- if( p0->Rank() == 0) +- e->Throw( "Expression must be an array in this context: "+ +- e->GetParString(0)); +- +- BaseGDL* p1 = e->GetNumericParDefined( 1); +- if( p1->Rank() == 0) +- e->Throw( "Expression must be an array in this context: "+ +- e->GetParString(1)); +- +- if( p0->N_Elements() <= p1->N_Elements()) +- e->Throw( "Incompatible dimensions for Array and Kernel."); +- +- // rank 1 for kernel works always +- if( p1->Rank() != 1) +- { +- SizeT rank = p0->Rank(); +- if( rank != p1->Rank()) +- e->Throw( "Incompatible dimensions for Array and Kernel."); +- +- for( SizeT r=0; rDim( r) <= p1->Dim( r)) +- e->Throw( "Incompatible dimensions for Array and Kernel."); +- } +- +- // convert kernel to array type +- auto_ptr p1Guard; +- if( p0->Type() == GDL_BYTE) +- { +- if( p1->Type() != GDL_INT) +- { +- p1 = p1->Convert2( GDL_INT, BaseGDL::COPY); +- p1Guard.reset( p1); +- } +- } +- else if( p0->Type() != p1->Type()) +- { +- p1 = p1->Convert2( p0->Type(), BaseGDL::COPY); +- p1Guard.reset( p1); +- } +- +- BaseGDL* scale; +- auto_ptr scaleGuard; +- if( nParam > 2) +- { +- scale = e->GetParDefined( 2); +- if( scale->Rank() > 0) +- e->Throw( "Expression must be a scalar in this context: "+ +- e->GetParString(2)); +- +- // p1 here handles GDL_BYTE case also +- if( p1->Type() != scale->Type()) +- { +- scale = scale->Convert2( p1->Type(),BaseGDL::COPY); +- scaleGuard.reset( scale); +- } +- } +- else +- { +- scale = p1->New( dimension(), BaseGDL::ZERO); +- } +- +- bool center = true; +- static int centerIx = e->KeywordIx( "CENTER"); +- if( e->KeywordPresent( centerIx)) +- { +- DLong c; +- e->AssureLongScalarKW( centerIx, c); +- center = (c != 0); +- } +- +- // overrides EDGE_TRUNCATE +- static int edge_wrapIx = e->KeywordIx( "EDGE_WRAP"); +- bool edge_wrap = e->KeywordSet( edge_wrapIx); +- static int edge_truncateIx = e->KeywordIx( "EDGE_TRUNCATE"); +- bool edge_truncate = e->KeywordSet( edge_truncateIx); +- +- int edgeMode = 0; +- if( edge_wrap) +- edgeMode = 1; +- else if( edge_truncate) +- edgeMode = 2; +- +- // p0, p1 and scale have same type +- // p1 has rank of 1 or same rank as p0 with each dimension smaller than p0 +- // scale is a scalar +- return p0->Convol( p1, scale, center, edgeMode); +- } +- +- BaseGDL* rebin_fun( EnvT* e) +- { +- SizeT nParam = e->NParam( 2); +- +- BaseGDL* p0 = e->GetNumericParDefined( 0); +- +- SizeT rank = p0->Rank(); +- +- if( rank == 0) +- e->Throw( "Expression must be an array in this context: "+ +- e->GetParString(0)); +- +- SizeT resDimInit[ MAXRANK]; +- +- DLongGDL* p1 = e->GetParAs(1); +- if (p1->Rank() > 0 && nParam > 2) +- e->Throw("The new dimensions must either be specified as an array or as a set of scalars."); +- SizeT np = p1->Rank() == 0 ? nParam : p1->N_Elements() + 1; +- +- for( SizeT p=1; pRank() == 0) e->AssureLongScalarPar( p, newDim); +- else newDim = (*p1)[p - 1]; +- +- if( newDim <= 0) +- e->Throw( "Array dimensions must be greater than 0."); +- +- if( rank >= p) +- { +- SizeT oldDim = p0->Dim( p-1); +- +- if( newDim > oldDim) +- { +- if( (newDim % oldDim) != 0) +- e->Throw( "Result dimensions must be integer factor " +- "of original dimensions."); +- } +- else +- { +- if( (oldDim % newDim) != 0) +- e->Throw( "Result dimensions must be integer factor " +- "of original dimensions."); +- } +- } +- +- resDimInit[ p-1] = newDim; +- } +- +- dimension resDim( resDimInit, np-1); +- +- static int sampleIx = e->KeywordIx( "SAMPLE"); +- bool sample = e->KeywordSet( sampleIx); +- +- return p0->Rebin( resDim, sample); +- } +- +- BaseGDL* obj_class( EnvT* e) +- { +- SizeT nParam = e->NParam(); +- +- static int countIx = e->KeywordIx( "COUNT"); +- static int superIx = e->KeywordIx( "SUPERCLASS"); +- +- bool super = e->KeywordSet( superIx); +- +- bool count = e->KeywordPresent( countIx); +- if( count) +- e->AssureGlobalKW( countIx); +- +- if( nParam > 0) +- { +- BaseGDL* p0 = e->GetParDefined( 0); +- +- if( p0->Type() != GDL_STRING && p0->Type() != GDL_OBJ) +- e->Throw( "Argument must be a scalar object reference or string: "+ +- e->GetParString(0)); +- +- if( !p0->Scalar()) +- e->Throw( "Expression must be a scalar or 1 element " +- "array in this context: "+e->GetParString(0)); +- +- DStructDesc* objDesc; +- +- if( p0->Type() == GDL_STRING) +- { +- DString objName; +- e->AssureScalarPar( 0, objName); +- objName = StrUpCase( objName); +- +- objDesc = FindInStructList( structList, objName); +- if( objDesc == NULL) +- { +- if( count) +- e->SetKW( countIx, new DLongGDL( 0)); +- return new DStringGDL( ""); +- } +- } +- else // GDL_OBJ +- { +- DObj objRef; +- e->AssureScalarPar( 0, objRef); +- +- if( objRef == 0) +- { +- if( count) +- e->SetKW( countIx, new DLongGDL( 0)); +- return new DStringGDL( ""); +- } +- +- DStructGDL* oStruct; +- try { +- oStruct = e->GetObjHeap( objRef); +- } +- catch ( GDLInterpreter::HeapException) +- { // non valid object +- if( count) +- e->SetKW( countIx, new DLongGDL( 0)); +- return new DStringGDL( ""); +- } +- +- objDesc = oStruct->Desc(); // cannot be NULL +- } +- +- if( !super) +- { +- if( count) +- e->SetKW( countIx, new DLongGDL( 1)); +- return new DStringGDL( objDesc->Name()); +- } +- +- deque< string> pNames; +- objDesc->GetParentNames( pNames); +- +- SizeT nNames = pNames.size(); +- +- if( count) +- e->SetKW( countIx, new DLongGDL( nNames)); +- +- if( nNames == 0) +- { +- return new DStringGDL( ""); +- } +- +- DStringGDL* res = new DStringGDL( dimension( nNames), +- BaseGDL::NOZERO); +- +- for( SizeT i=0; iThrow( "Conflicting keywords."); +- +- SizeT nObj = structList.size(); +- +- DStringGDL* res = new DStringGDL( dimension( nObj), +- BaseGDL::NOZERO); +- +- for( SizeT i=0; iName(); +- } +- +- return res; +- } +- +- BaseGDL* obj_isa( EnvT* e) +- { +- SizeT nParam = e->NParam( 2); +- +- BaseGDL* p0 = e->GetPar( 0); +- if( p0 == NULL || p0->Type() != GDL_OBJ) +- e->Throw( "Object reference type required in this context: "+ +- e->GetParString(0)); +- +- DString className; +- e->AssureScalarPar( 1, className); +- className = StrUpCase( className); +- +- DObjGDL* pObj = static_cast( p0); +- +- DByteGDL* res = new DByteGDL( pObj->Dim()); // zero +- +- GDLInterpreter* interpreter = e->Interpreter(); +- +- SizeT nElem = pObj->N_Elements(); +- for( SizeT i=0; iObjValid( (*pObj)[ i])) +- { +- DStructGDL* oStruct = e->GetObjHeap( (*pObj)[i]); +- if( oStruct->Desc()->IsParent( className)) +- (*res)[i] = 1; +- } +- } +- +- return res; +- } +- +- BaseGDL* n_tags( EnvT* e) +- { +- e->NParam( 1); +- +- BaseGDL* p0 = e->GetPar( 0); +- if( p0 == NULL) +- return new DLongGDL( 0); +- +- if( p0->Type() != GDL_STRUCT) +- return new DLongGDL( 0); +- +- DStructGDL* s = static_cast( p0); +- +- //static int lengthIx = e->KeywordIx( "DATA_LENGTH"); +- //bool length = e->KeywordSet( lengthIx); +- +- // we don't know now how to distinghuis the 2 following cases +- if(e->KeywordSet("DATA_LENGTH")) +- return new DLongGDL( s->Sizeof()); +- +- if(e->KeywordSet("LENGTH")) +- return new DLongGDL( s->Sizeof()); +- +- return new DLongGDL( s->Desc()->NTags()); +- } +- +- BaseGDL* bytscl( EnvT* e) +- { +- SizeT nParam = e->NParam( 1); +- +- BaseGDL* p0=e->GetNumericParDefined( 0); +- +- static int minIx = e->KeywordIx( "MIN"); +- static int maxIx = e->KeywordIx( "MAX"); +- static int topIx = e->KeywordIx( "TOP"); +- bool omitNaN = e->KeywordPresent( 3); +- +- DLong topL=255; +- if( e->GetKW( topIx) != NULL) +- e->AssureLongScalarKW( topIx, topL); +- DByte top = static_cast(topL); +- DDouble dTop = static_cast(top); +- +- DDouble min; +- bool minSet = false; +- // SA: handling 3 parameters to emulate undocumented IDL behaviour +- // of translating second and third arguments to MIN and MAX, respectively +- // (parameters have precedence over keywords) +- if (nParam >= 2) +- { +- e->AssureDoubleScalarPar(1, min); +- minSet = true; +- } +- else if (e->GetKW(minIx) != NULL) +- { +- e->AssureDoubleScalarKW(minIx, min); +- minSet = true; +- } +- +- DDouble max; +- bool maxSet = false; +- if (nParam == 3) +- { +- e->AssureDoubleScalarPar(2, max); +- maxSet = true; +- } +- else if (e->GetKW(maxIx) != NULL) +- { +- e->AssureDoubleScalarKW(maxIx, max); +- maxSet = true; +- } +- +- DDoubleGDL* dRes = +- static_cast(p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)); +- +- DLong maxEl, minEl; +- if( !maxSet || !minSet) +- dRes->MinMax( &minEl, &maxEl, NULL, NULL, omitNaN); +- if( !minSet) +- min = (*dRes)[ minEl]; +- if( !maxSet) +- max = (*dRes)[ maxEl]; +- +- SizeT nEl = dRes->N_Elements(); +- for( SizeT i=0; i= max) (*dRes)[ i] = dTop; +- else +- { +- // SA: floor is used for integer types to simulate manipulation on input data types +- if (IntType(p0->Type())) (*dRes)[ i] = floor(((dTop + 1.)*(d - min) - 1.) / (max-min)); +- // SA (?): here floor is used (instead of round) to simulate IDL behaviour +- else (*dRes)[ i] = floor((d - min) / (max-min) * (dTop + .9999)); +- } +- } +- +- return dRes->Convert2( GDL_BYTE); +- } +- +- BaseGDL* strtok_fun( EnvT* e) +- { +- SizeT nParam=e->NParam( 1); +- +- DString stringIn; +- e->AssureStringScalarPar( 0, stringIn); +- +- DString pattern = " \t"; +- if(nParam > 1) { +- e->AssureStringScalarPar( 1, pattern); +- } +- +- static int extractIx = e->KeywordIx( "EXTRACT"); +- bool extract = e->KeywordSet( extractIx); +- +- static int lengthIx = e->KeywordIx( "LENGTH"); +- bool lengthPresent = e->KeywordPresent( lengthIx); +- +- if( extract && lengthPresent) +- e->Throw( "Conflicting keywords."); +- +- static int pre0Ix = e->KeywordIx( "PRESERVE_NULL"); +- bool pre0 = e->KeywordSet( pre0Ix); +- +- static int regexIx = e->KeywordIx( "REGEX"); +- bool regex = e->KeywordPresent( regexIx); +- char err_msg[MAX_REGEXPERR_LENGTH]; +- regex_t regexp; +- +- deque tokenStart; +- deque tokenLen; +- +- int strLen = stringIn.length(); +- +- DString escape = ""; +- e->AssureStringScalarKWIfPresent( "ESCAPE", escape); +- deque escList; +- long pos = 0; +- while(pos != string::npos) +- { +- pos = stringIn.find_first_of( escape, pos); +- if( pos != string::npos) +- { +- escList.push_back( pos+1); // remember escaped char +- pos += 2; // skip escaped char +- } +- } +- deque::iterator escBeg = escList.begin(); +- deque::iterator escEnd = escList.end(); +- +- long tokB = 0; +- long tokE; +- long nextE = 0; +- long actLen; +- +- // If regex then compile regex +- if( regex) { +- if (pattern == " \t") pattern = " "; // regcomp doesn't like "\t" JMG +- int compRes = regcomp( ®exp, pattern.c_str(), REG_EXTENDED); +- if (compRes) { +- regerror(compRes, ®exp, err_msg, MAX_REGEXPERR_LENGTH); +- e->Throw( "Error processing regular expression: "+ +- pattern+"\n "+string(err_msg)+"."); +- } +- } +- +- for(;;) +- { +- regmatch_t pmatch[1]; +- if( regex) { +- int matchres = regexec( ®exp, stringIn.c_str()+nextE, 1, pmatch, 0); +- tokE = matchres? -1:pmatch[0].rm_so; +- } else { +- tokE = stringIn.find_first_of( pattern, nextE); +- } +- +- if( tokE == string::npos) +- { +- actLen = strLen - tokB; +- if( actLen > 0 || pre0) +- { +- tokenStart.push_back( tokB); +- tokenLen.push_back( actLen); +- } +- break; +- } +- +- if( find( escBeg, escEnd, tokE) == escEnd) +- { +- if (regex) actLen = tokE; else actLen = tokE - tokB; +- if( actLen > 0 || pre0) +- { +- tokenStart.push_back( tokB); +- tokenLen.push_back( actLen); +- } +- if (regex) tokB += pmatch[0].rm_eo; else tokB = tokE + 1; +- } +- if (regex) nextE += pmatch[0].rm_eo; else nextE = tokE + 1; +- } // for(;;) +- +- if (regex) regfree( ®exp); +- +- SizeT nTok = tokenStart.size(); +- +- if( !extract) +- { +- if( lengthPresent) +- { +- e->AssureGlobalKW( lengthIx); +- +- if( nTok > 0) +- { +- dimension dim(nTok); +- DLongGDL* len = new DLongGDL(dim); +- for(int i=0; i < nTok; i++) +- (*len)[i] = tokenLen[i]; +- +- e->SetKW( lengthIx, len); +- } +- else +- { +- e->SetKW( lengthIx, new DLongGDL( 0)); +- } +- } +- +- if( nTok == 0) return new DLongGDL( 0); +- +- dimension dim(nTok); +- DLongGDL* d = new DLongGDL(dim); +- for(int i=0; i < nTok; i++) +- (*d)[i] = tokenStart[i]; +- return d; +- } +- +- // EXTRACT +- if( nTok == 0) return new DStringGDL( ""); +- +- dimension dim(nTok); +- DStringGDL *d = new DStringGDL(dim); +- for(int i=0; i < nTok; i++) +- { +- (*d)[i] = stringIn.substr(tokenStart[i], tokenLen[i]); +- +- // remove escape +- DString& act = (*d)[i]; +- long escPos = act.find_first_of( escape, 0); +- while( escPos != string::npos) +- { +- act = act.substr( 0, escPos)+act.substr( escPos+1); +- escPos = act.find_first_of( escape, escPos+1); +- } +- } +- return d; +- } +- +- BaseGDL* getenv_fun( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- +- static int environmentIx = e->KeywordIx( "ENVIRONMENT" ); +- bool environment = e->KeywordSet( environmentIx ); +- +- SizeT nEnv; +- DStringGDL* env; +- +- if( environment) { +- +- if(nParam != 0) +- e->Throw( "Incorrect number of arguments."); +- +- // determine number of environment entries +- for(nEnv = 0; environ[nEnv] != NULL ; ++nEnv); +- +- dimension dim( nEnv ); +- env = new DStringGDL(dim); +- +- // copy stuff into local string array +- for(SizeT i=0; i < nEnv ; ++i) +- (*env)[i] = environ[i]; +- +- } else { +- +- if(nParam != 1) +- e->Throw( "Incorrect number of arguments."); +- +- DStringGDL* name = e->GetParAs(0); +- nEnv = name->N_Elements(); +- +- env = new DStringGDL( name->Dim()); +- +- // copy the stuff into local string only if param found +- char *resPtr; +- for(SizeT i=0; i < nEnv ; ++i) +- { +- // handle special environment variables +- // GDL_TMPDIR, IDL_TMPDIR +- if( (*name)[i] == "GDL_TMPDIR" || (*name)[i] == "IDL_TMPDIR") +- { +- resPtr = getenv((*name)[i].c_str()); +- +- if( resPtr != NULL) +- (*env)[i] = resPtr; +- else +- (*env)[i] = SysVar::Dir(); +- +- AppendIfNeeded( (*env)[i], "/"); +- } +- else // normal environment variables +- if( (resPtr = getenv((*name)[i].c_str())) ) +- (*env)[i] = resPtr; +- } +- } +- +- return env; +- } +- +- BaseGDL* tag_names_fun( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- DStructGDL* struc= e->GetParAs(0); +- +- static int structureNameIx = e->KeywordIx( "STRUCTURE_NAME" ); +- bool structureName = e->KeywordSet( structureNameIx ); +- +- DStringGDL* tagNames; +- +- if(structureName){ +- +- if ((*struc).Desc()->Name() != "$truct") +- tagNames = new DStringGDL((*struc).Desc()->Name()); +- else +- tagNames = new DStringGDL(""); +- +- } else { +- SizeT nTags = (*struc).Desc()->NTags(); +- +- tagNames = new DStringGDL(dimension(nTags)); +- for(int i=0; i < nTags; ++i) +- (*tagNames)[i] = (*struc).Desc()->TagName(i); +- } +- +- return tagNames; +- } +- +-// AC 12-Oc-2011: better version for: len=len, /Extract and /Sub +-// but it is still not perfect +- +- BaseGDL* stregex_fun( EnvT* e) +- { +- SizeT nParam=e->NParam( 2); +- +- DStringGDL* stringExpr= e->GetParAs(0); +- dimension dim = stringExpr->Dim(); +- +- DString pattern; +- e->AssureStringScalarPar(1, pattern); +- if (pattern.size() <= 0) +- { +- e->Throw( "Error processing regular expression: "+pattern+ +- "\n empty (sub)expression"); +- } +- +- static int booleanIx = e->KeywordIx( "BOOLEAN" ); +- bool booleanKW = e->KeywordSet( booleanIx ); +- +- static int extractIx = e->KeywordIx( "EXTRACT" ); +- bool extractKW = e->KeywordSet( extractIx ); +- +- static int foldCaseIx = e->KeywordIx( "FOLD_CASE" ); +- bool foldCaseKW = e->KeywordSet( foldCaseIx ); +- +- //XXXpch: this is wrong, should check arg_present +- static int lengthIx = e->KeywordIx( "LENGTH" ); +- bool lengthKW = e->KeywordPresent( lengthIx ); +- +- static int subexprIx = e->KeywordIx( "SUBEXPR" ); +- bool subexprKW = e->KeywordSet( subexprIx ); +- +- if( booleanKW && (subexprKW || extractKW || lengthKW)) +- e->Throw( "Conflicting keywords."); +- +- char err_msg[MAX_REGEXPERR_LENGTH]; +- +- // set the compile flags +- int cflags = REG_EXTENDED; +- if (foldCaseKW) +- cflags |= REG_ICASE; +- if (booleanKW) +- cflags |= REG_NOSUB; +- +- // compile the regular expression +- regex_t regexp; +- int compRes = regcomp( ®exp, pattern.c_str(), cflags); +- SizeT nSubExpr = regexp.re_nsub + 1; +- +- // cout << regexp.re_nsub << endl; +- +- if (compRes) { +- regerror(compRes, ®exp, err_msg, MAX_REGEXPERR_LENGTH); +- e->Throw( "Error processing regular expression: "+ +- pattern+"\n "+string(err_msg)+"."); +- } +- +- BaseGDL* result; +- +- if( booleanKW) +- result = new DByteGDL(dim); +- else if( extractKW && !subexprKW) +- { +- // cout << "my pb ! ? dim= " << dim << endl; +- result = new DStringGDL(dim); +- } +- else if( subexprKW) +- { +- // cout << "my pb 2 ? dim= " << dim << endl; +- dimension subExprDim = dim; +- subExprDim >> nSubExpr; // m_schellens: commented in, needed +- if( extractKW) +- result = new DStringGDL(subExprDim); +- else +- result = new DLongGDL(subExprDim); +- } +- else +- result = new DLongGDL(dim); +- +- DLongGDL* len = NULL; +- if( lengthKW) { +- e->AssureGlobalKW( lengthIx); +- if( subexprKW) +- { +- dimension subExprDim = dim; +- subExprDim >> nSubExpr; // m_schellens: commented in, needed +- len = new DLongGDL(subExprDim); +- } +- else +- { +- len = new DLongGDL(dim); +- } +- for( SizeT i=0; iN_Elements(); ++i) +- (*len)[i]= -1; +- } +- +- int nmatch = 1; +- if( subexprKW) nmatch = nSubExpr; +- +- regmatch_t* pmatch = new regmatch_t[nSubExpr]; +- ArrayGuard pmatchGuard( pmatch); +- +- // cout << "dim " << dim.NDimElements() << endl; +- for( SizeT s=0; s(result))[i+s*nSubExpr] = +- (*stringExpr)[s].substr( pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so); +-// (*stringExpr)[i+s*nSubExpr].substr( pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so); +- if( lengthKW) +- (*len)[i+s*nSubExpr] = pmatch[i].rm_so != -1 ? pmatch[i].rm_eo - pmatch[i].rm_so : -1; +-// (*len)[i+s*nSubExpr] = pmatch[i].rm_eo - pmatch[i].rm_so; +- } +- } +- else if ( subexprKW) +- { +- // cout << "je ne comprends pas v2: "<< nSubExpr << endl; +- +- // Loop through subexpressions & fill output array +- for( SizeT i = 0; i(result))[i+s*nSubExpr] = pmatch[i].rm_so; +- if( lengthKW) +- (*len)[i+s*nSubExpr] = pmatch[i].rm_so != -1 ? pmatch[i].rm_eo - pmatch[i].rm_so : -1; +- } +- } +- else +- { +- if( booleanKW) +- (* static_cast(result))[s] = (matchres == 0); +- else if ( extractKW) // !subExprKW +- { +- if( matchres == 0) +- (* static_cast(result))[s] = +- (*stringExpr)[s].substr( pmatch[0].rm_so, +- pmatch[0].rm_eo - pmatch[0].rm_so); +- } +- else +- (*static_cast(result))[s] = matchres ? -1 : pmatch[0].rm_so; +- } +- +- if( lengthKW && !subexprKW) +- (*len)[s] = pmatch[0].rm_eo - pmatch[0].rm_so; +- } +- +- regfree( ®exp); +- +- if( lengthKW) +- e->SetKW( lengthIx, len); +- +- return result; +- } +- +- BaseGDL* routine_info( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- +- static int functionsIx = e->KeywordIx( "FUNCTIONS" ); +- bool functionsKW = e->KeywordSet( functionsIx ); +- static int systemIx = e->KeywordIx( "SYSTEM" ); +- bool systemKW = e->KeywordSet( systemIx ); +- static int disabledIx = e->KeywordIx( "DISABLED" ); +- bool disabledKW = e->KeywordSet( disabledIx ); +- static int parametersIx = e->KeywordIx( "PARAMETERS" ); +- bool parametersKW = e->KeywordSet( parametersIx ); +- +- if (parametersKW) +- { +- // sanity checks +- if (systemKW || disabledKW) e->Throw("Conflicting keywords."); +- if (nParam != 1) e->Throw("Incorrect number of arguments."); +- +- // getting the routine name from the first parameter +- DString name; +- e->AssureScalarPar(0, name); +- name = StrUpCase(name); +- +- DSubUD* routine = functionsKW +- ? static_cast(funList[GDLInterpreter::GetFunIx(name)]) +- : static_cast(proList[GDLInterpreter::GetProIx(name)]); +- SizeT np = routine->NPar(), nk = routine->NKey(); +- +- // creating the output anonymous structure +- DStructDesc* stru_desc = new DStructDesc("$truct"); +- SpDLong aLong; +- stru_desc->AddTag("NUM_ARGS", &aLong); +- stru_desc->AddTag("NUM_KW_ARGS", &aLong); +- if (np > 0) +- { +- SpDString aStringArr(dimension((int)np)); +- stru_desc->AddTag("ARGS", &aStringArr); +- } +- if (nk > 0) +- { +- SpDString aStringArr(dimension((int)nk)); +- stru_desc->AddTag("KW_ARGS", &aStringArr); +- } +- DStructGDL* stru = new DStructGDL(stru_desc, dimension()); +- +- // filling the structure with information about the routine +- stru->InitTag("NUM_ARGS", DLongGDL(np)); +- stru->InitTag("NUM_KW_ARGS", DLongGDL(nk)); +- if (np > 0) +- { +- DStringGDL *pnames = new DStringGDL(dimension(np)); +- for (SizeT p = 0; p < np; ++p) (*pnames)[p] = routine->GetVarName(nk + p); +- stru->InitTag("ARGS", *pnames); +- GDLDelete(pnames); +- } +- if (nk > 0) +- { +- DStringGDL *knames = new DStringGDL(dimension(nk)); +- for (SizeT k = 0; k < nk; ++k) (*knames)[k] = routine->GetKWName(k); +- stru->InitTag("KW_ARGS", *knames); +- GDLDelete(knames); +- } +- +- // returning +- return stru; +- } +- +- // GDL does not have disabled routines +- if( disabledKW) return new DStringGDL(""); +- +- // if( functionsKW || systemKW || nParam == 0) +- // { +- deque subList; +- +- if( functionsKW) +- { +- if( systemKW) +- { +- SizeT n = libFunList.size(); +- if( n == 0) return new DStringGDL(""); +- +- DStringGDL* res = new DStringGDL( dimension( n), BaseGDL::NOZERO); +- for( SizeT i = 0; iObjectName(); +- +- return res; +- } +- else +- { +- SizeT n = funList.size(); +- if( n == 0) return new DStringGDL(""); +- subList.resize( n); +- +- for( SizeT i = 0; iObjectName()); +- } +- } +- else +- { +- if( systemKW) +- { +- SizeT n = libProList.size(); +- if( n == 0) return new DStringGDL(""); +- +- DStringGDL* res = new DStringGDL( dimension( n), BaseGDL::NOZERO); +- for( SizeT i = 0; iObjectName(); +- +- return res; +- } +- else +- { +- SizeT n = proList.size(); +- if( n == 0) return new DStringGDL(""); +- subList.resize( n); +- +- for( SizeT i = 0; iObjectName()); +- } +- } +- +- sort( subList.begin(), subList.end()); +- SizeT nS = subList.size(); +- +- DStringGDL* res = new DStringGDL( dimension( nS), BaseGDL::NOZERO); +- for( SizeT s=0; s +- rl_prep_terminal (0); +-#endif +- +- SizeT nParam=e->NParam(); +- +- bool doWait = true; +- if( nParam > 0) +- { +- doWait = false; +- DLong waitArg = 0; +- e->AssureLongScalarPar( 0, waitArg); +- if( waitArg != 0) +- { +- doWait = true; +- } +- } +- +- // https://sourceforge.net/forum/forum.php?thread_id=3292183&forum_id=338691 +- // DONE: Implement proper SCALAR parameter handling (doWait variable) +- // which is/was not blocking in the original program. +- // note: multi-byte input is not supported here. +- +- char c='\0'; //initialize is never a bad idea... +- +- int fd=fileno(stdin); +-#ifndef _MSC_VER +- struct termios orig, get; +-#endif +- // Get terminal setup to revert to it at end. +-#ifndef _MSC_VER +- (void)tcgetattr(fd, &orig); +- // New terminal setup, non-canonical. +- get.c_lflag = ISIG; +-#endif +- if (doWait) +- { +- // will wait for a character +-#ifndef _MSC_VER +- get.c_cc[VTIME]=0; +- get.c_cc[VMIN]=1; +- (void)tcsetattr(fd, TCSANOW, &get); +-#endif +- cin.get(c); +- } +- else +- { +- // will not wait, but return EOF or next character in terminal buffer if present +-#ifndef _MSC_VER +- get.c_cc[VTIME]=0; +- get.c_cc[VMIN]=0; +- (void)tcsetattr(fd, TCSANOW, &get); +-#endif +- //the trick is *not to use C++ functions here. cin.get would wait.* +- c=std::fgetc(stdin); +- //and to convert EOF to null (otherwise GDL may exit if not compiled with +- //[lib][n]curses) +- if(c==EOF) c='\0'; +- } +- +- // Restore original terminal settings. +-#ifndef _MSC_VER +- (void)tcsetattr(fd, TCSANOW, &orig); +-#endif +-#if defined(HAVE_LIBREADLINE) +- rl_deprep_terminal (); +-#endif +- +- DStringGDL* res = new DStringGDL( DString( i2s( c))); +- +- return res; +- +- } +- +- +- BaseGDL* temporary( EnvT* e) +- { +- SizeT nParam=e->NParam(1); +- +- BaseGDL** p0 = &e->GetParDefined( 0); +- +- BaseGDL* ret = *p0; +- +- *p0 = NULL; // make parameter undefined +- return ret; +- } +- +- BaseGDL* memory( EnvT* e) +- { +- SizeT nParam=e->NParam( 0); +- +- BaseGDL* ret; +- bool kw_l64 = e->KeywordSet(e->KeywordIx("L64")); +- // TODO: IDL-doc mentions about automatically switching to L64 if needed +- +- if (e->KeywordSet(e->KeywordIx("STRUCTURE"))) +- { +- // returning structure +- if (kw_l64) +- { +- ret = new DStructGDL("IDL_MEMORY64"); +- DStructGDL* retStru = static_cast(ret); +- (retStru->GetTag(retStru->Desc()->TagIndex("CURRENT")))->InitFrom( DLong64GDL(MemStats::GetCurrent())); +- (retStru->GetTag(retStru->Desc()->TagIndex("NUM_ALLOC")))->InitFrom( DLong64GDL(MemStats::GetNumAlloc())); +- (retStru->GetTag(retStru->Desc()->TagIndex("NUM_FREE")))->InitFrom( DLong64GDL(MemStats::GetNumFree())); +- (retStru->GetTag(retStru->Desc()->TagIndex("HIGHWATER")))->InitFrom( DLong64GDL(MemStats::GetHighWater())); +- } +- else +- { +- ret = new DStructGDL("IDL_MEMORY"); +- DStructGDL* retStru = static_cast(ret); +- (retStru->GetTag(retStru->Desc()->TagIndex("CURRENT")))->InitFrom( DLongGDL(MemStats::GetCurrent())); +- (retStru->GetTag(retStru->Desc()->TagIndex("NUM_ALLOC")))->InitFrom( DLongGDL(MemStats::GetNumAlloc())); +- (retStru->GetTag(retStru->Desc()->TagIndex("NUM_FREE")))->InitFrom( DLongGDL(MemStats::GetNumFree())); +- (retStru->GetTag(retStru->Desc()->TagIndex("HIGHWATER")))->InitFrom( DLongGDL(MemStats::GetHighWater())); +- } +- } +- else +- { +- bool kw_current = e->KeywordSet(e->KeywordIx("CURRENT")); +- bool kw_num_alloc = e->KeywordSet(e->KeywordIx("NUM_ALLOC")); +- bool kw_num_free = e->KeywordSet(e->KeywordIx("NUM_FREE")); +- bool kw_highwater = e->KeywordSet(e->KeywordIx("HIGHWATER")); +- +- // Following the IDL documentation: mutually exclusive keywords +- // IDL behaves different, incl. segfaults with selected kw combinations +- if (kw_current + kw_num_alloc + kw_num_free + kw_highwater > 1) +- e->Throw("CURRENT, NUM_ALLOC, NUM_FREE & HIGHWATER keywords" +- " are mutually exclusive"); +- +- if (kw_current) +- { +- if (kw_l64) ret = new DLong64GDL(MemStats::GetCurrent()); +- else ret = new DLongGDL(MemStats::GetCurrent()); +- } +- else if (kw_num_alloc) +- { +- if (kw_l64) ret = new DLong64GDL(MemStats::GetNumAlloc()); +- else ret = new DLongGDL(MemStats::GetNumAlloc()); +- } +- else if (kw_num_free) +- { +- if (kw_l64) ret = new DLong64GDL(MemStats::GetNumFree()); +- else ret = new DLongGDL(MemStats::GetNumFree()); +- } +- else if (kw_highwater) +- { +- if (kw_l64) ret = new DLong64GDL(MemStats::GetHighWater()); +- else ret = new DLongGDL(MemStats::GetHighWater()); +- } +- else +- { +- // returning 4-element array +- if (kw_l64) +- { +- ret = new DLong64GDL(dimension(4)); +- (*static_cast(ret))[0] = MemStats::GetCurrent(); +- (*static_cast(ret))[1] = MemStats::GetNumAlloc(); +- (*static_cast(ret))[2] = MemStats::GetNumFree(); +- (*static_cast(ret))[3] = MemStats::GetHighWater(); +- } +- else +- { +- ret = new DLongGDL(dimension(4)); +- (*static_cast(ret))[0] = MemStats::GetCurrent(); +- (*static_cast(ret))[1] = MemStats::GetNumAlloc(); +- (*static_cast(ret))[2] = MemStats::GetNumFree(); +- (*static_cast(ret))[3] = MemStats::GetHighWater(); +- } +- } +- } +- +- return ret; +- } +- +- inline DByte StrCmp( const string& s1, const string& s2, DLong n) +- { +- if( n <= 0) return 1; +- if( s1.substr(0,n) == s2.substr(0,n)) return 1; +- return 0; +- } +- inline DByte StrCmp( const string& s1, const string& s2) +- { +- if( s1 == s2) return 1; +- return 0; +- } +- inline DByte StrCmpFold( const string& s1, const string& s2, DLong n) +- { +- if( n <= 0) return 1; +- if( StrUpCase( s1.substr(0,n)) == StrUpCase(s2.substr(0,n))) return 1; +- return 0; +- } +- inline DByte StrCmpFold( const string& s1, const string& s2) +- { +- if( StrUpCase( s1) == StrUpCase(s2)) return 1; +- return 0; +- } +- +- BaseGDL* strcmp_fun( EnvT* e) +- { +- SizeT nParam=e->NParam(2); +- +- DStringGDL* s0 = static_cast( e->GetParAs< DStringGDL>( 0)); +- DStringGDL* s1 = static_cast( e->GetParAs< DStringGDL>( 1)); +- +- DLongGDL* l2 = NULL; +- if( nParam > 2) +- { +- l2 = static_cast( e->GetParAs< DLongGDL>( 2)); +- } +- +- static int foldIx = e->KeywordIx( "FOLD_CASE"); +- bool fold = e->KeywordSet( foldIx ); +- +- if( s0->Scalar() && s1->Scalar()) +- { +- if( l2 == NULL) +- { +- if( fold) +- return new DByteGDL( StrCmpFold( (*s0)[0], (*s1)[0])); +- else +- return new DByteGDL( StrCmp( (*s0)[0], (*s1)[0])); +- } +- else +- { +- DByteGDL* res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); +- SizeT nEl = l2->N_Elements(); +- if( fold) +- for( SizeT i=0; iScalar()) +- { +- DByteGDL* res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); +- SizeT nEl = s1->N_Elements(); +- if( fold) +- for( SizeT i=0; iScalar()) +- { +- DByteGDL* res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); +- SizeT nEl = s0->N_Elements(); +- if( fold) +- for( SizeT i=0; iN_Elements() <= s1->N_Elements()) +- { +- res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); +- nEl = s0->N_Elements(); +- } +- else +- { +- res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); +- nEl = s1->N_Elements(); +- } +- if( fold) +- for( SizeT i=0; iScalar(); +- if( s0->Scalar()) +- { +- if( l2Scalar || s1->N_Elements() <= l2->N_Elements()) +- { +- res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); +- nEl = s1->N_Elements(); +- } +- else +- { +- res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); +- nEl = l2->N_Elements(); +- } +- if( fold) +- for( SizeT i=0; iScalar()) +- { +- if( l2Scalar || s0->N_Elements() <= l2->N_Elements()) +- { +- res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); +- nEl = s0->N_Elements(); +- } +- else +- { +- res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); +- nEl = l2->N_Elements(); +- } +- if( fold) +- for( SizeT i=0; iN_Elements() <= s1->N_Elements()) +- { +- res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); +- nEl = s0->N_Elements(); +- } +- else +- { +- res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); +- nEl = s1->N_Elements(); +- } +- else +- { +- if( s0->N_Elements() <= s1->N_Elements()) +- if( s0->N_Elements() <= l2->N_Elements()) +- { +- res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); +- nEl = s0->N_Elements(); +- } +- else +- { +- res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); +- nEl = l2->N_Elements(); +- } +- else +- if( s1->N_Elements() <= l2->N_Elements()) +- { +- res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); +- nEl = s1->N_Elements(); +- } +- else +- { +- res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); +- nEl = l2->N_Elements(); +- } +- } +- if( fold) +- for( SizeT i=0; i 'Z')) +- e->Throw( "Illegal tag name: "+name+"."); +- for( SizeT i=1; i 'Z') && +- (n[i] < '0' || n[i] > '9')) +- e->Throw( "Illegal tag name: "+name+"."); +- } +- return n; +- } +- +- BaseGDL* create_struct( EnvT* e) +- { +- static int nameIx = e->KeywordIx( "NAME" ); +- DString name = "$truct"; +- if( e->KeywordPresent( nameIx)) { +- // Check if name exists, if not then treat as unnamed +- if (e->GetKW( nameIx) != NULL) +- e->AssureStringScalarKW( nameIx, name); +- } +- +- if( name != "$truct") // named struct +- { +- name = StrUpCase( name); +- +- SizeT nParam=e->NParam(); +- +- if( nParam == 0) +- { +- DStructDesc* desc = +- e->Interpreter()->GetStruct( name, e->CallingNode()); +- +- dimension dim( 1); +- return new DStructGDL( desc, dim); +- } +- +- DStructDesc* nStructDesc; +- auto_ptr nStructDescGuard; +- +- DStructDesc* oStructDesc= +- FindInStructList( structList, name); +- +- if( oStructDesc == NULL || oStructDesc->NTags() > 0) +- { +- // not defined at all yet (-> define now) +- // or completely defined (-> define now and check equality) +- nStructDesc= new DStructDesc( name); +- +- // guard it +- nStructDescGuard.reset( nStructDesc); +- } +- else +- { +- // NTags() == 0 +- // not completely defined (only name in list) +- nStructDesc= oStructDesc; +- } +- +- // the instance variable +- // dimension dim( 1); +- // DStructGDL* instance = new DStructGDL( nStructDesc, dim); +- DStructGDL* instance = new DStructGDL( nStructDesc); +- auto_ptr instance_guard(instance); +- +- for( SizeT p=0; pGetParDefined( p); +- DStructGDL* parStruct = dynamic_cast( par); +- if( parStruct != NULL) +- { +- // add struct +- if( !parStruct->Scalar()) +- e->Throw("Expression must be a scalar in this context: "+ +- e->GetParString( p)); +- +- DStructDesc* desc = parStruct->Desc(); +- for( SizeT t=0; t< desc->NTags(); ++t) +- { +- instance->NewTag( desc->TagName( t), +- parStruct->GetTag( t)->Dup()); +- } +- } +- else +- { +- // add tag value pair +- DStringGDL* tagNames = e->GetParAs( p); +- SizeT nTags = tagNames->N_Elements(); +- +- SizeT tagStart = p+1; +- SizeT tagEnd = p+nTags; +- if( tagEnd >= nParam) +- e->Throw( "Incorrect number of arguments."); +- +- do{ +- ++p; +- BaseGDL* value = e->GetParDefined( p); +- +- // add +- instance->NewTag( TagName( e, (*tagNames)[ p-tagStart]), +- value->Dup()); +- } +- while( pAssureIdentical(nStructDesc); +- instance->DStructGDL::SetDesc(oStructDesc); +- //delete nStructDesc; // auto_ptr +- } +- } +- else +- { +- // release from guard (if not NULL) +- nStructDescGuard.release(); +- // insert into struct list +- structList.push_back(nStructDesc); +- } +- +- instance_guard.release(); +- return instance; +- } +- else +- { // unnamed struc +- +- // Handle case of single structure parameter +- SizeT nParam; +- nParam = e->NParam(1); +- BaseGDL* par = e->GetParDefined( 0); +- DStructGDL* parStruct = dynamic_cast( par); +- if (nParam != 1 || parStruct == NULL) +- nParam=e->NParam(2); +- +- DStructDesc* nStructDesc = new DStructDesc( "$truct"); +- // instance takes care of nStructDesc since it is unnamed +- // dimension dim( 1); +- // DStructGDL* instance = new DStructGDL( nStructDesc, dim); +- DStructGDL* instance = new DStructGDL( nStructDesc); +- auto_ptr instance_guard(instance); +- +- for( SizeT p=0; pGetParDefined( p); +- DStructGDL* parStruct = dynamic_cast( par); +- if( parStruct != NULL) +- { +- // add struct +- if( !parStruct->Scalar()) +- e->Throw("Expression must be a scalar in this context: "+ +- e->GetParString( p)); +- +- DStructDesc* desc = parStruct->Desc(); +- for( SizeT t=0; t< desc->NTags(); ++t) +- { +- instance->NewTag( desc->TagName( t), +- parStruct->GetTag( t)->Dup()); +- } +- ++p; +- } +- else +- { +- // add tag value pair +- DStringGDL* tagNames = e->GetParAs( p); +- SizeT nTags = tagNames->N_Elements(); +- +- SizeT tagStart = p+1; +- SizeT tagEnd = p+nTags; +- if( tagEnd >= nParam) +- e->Throw( "Incorrect number of arguments."); +- +- for(++p; p<=tagEnd; ++p) +- { +- BaseGDL* value = e->GetParDefined( p); +- +- // add +- instance->NewTag( TagName( e, (*tagNames)[ p-tagStart]), +- value->Dup()); +- } +- } +- } +- +- instance_guard.release(); +- return instance; +- } +- } +- +- BaseGDL* rotate( EnvT* e) +- { +- e->NParam(2); +- BaseGDL* p0 = e->GetParDefined( 0); +- +- if( p0->Rank() == 0) +- e->Throw( "Expression must be an array in this context: " + e->GetParString( 0)); +- +- if( p0->Rank() != 1 && p0->Rank() != 2) +- e->Throw( "Only 1 or 2 dimensions allowed: " + e->GetParString( 0)); +- +- if( p0->Type() == GDL_STRUCT) +- e->Throw( "STRUCT expression not allowed in this context: "+ +- e->GetParString( 0)); +- +- DLong dir; +- e->AssureLongScalarPar( 1, dir); +- +- return p0->Rotate( dir); +- } +- +- // SA: based on the code of rotate() (above) +- BaseGDL* reverse( EnvT* e) +- { +- e->NParam(1); +- BaseGDL* p0 = e->GetParDefined(0); +- if (p0->Rank() == 0) return p0->Dup(); +- +- DLong dim = 1; +- if (e->GetPar(1) != NULL) +- e->AssureLongScalarPar(1, dim); +- if (p0->Rank() != 0 && (dim > p0->Rank() || dim < 1)) +- e->Throw("Subscript_index must be positive and less than or equal to number of dimensions."); +- +- BaseGDL* ret; +- // IDL doc states that OVERWRITE is ignored for one- or two-dim. arrays +- // but it seems to behave differently +- // if (p0->Rank() > 2 && e->KeywordSet("OVERWRITE") && e->GlobalPar(0)) +- if (e->KeywordSet("OVERWRITE")) +- { +- p0->Reverse(dim-1); +- bool stolen = e->StealLocalPar( 0); +- if( !stolen) e->GetPar(0) = NULL; +- return p0; +- } +- else ret = p0->DupReverse(dim - 1); +- return ret; +- } +- +- // SA: parse_url based on the PHP parse_url() function code +- // by Jim Winstead / The PHP Group (PHP license v. 3.01) +- // (http://svn.php.net/viewvc/php/php-src/trunk/ext/standard/url.c) +- // PHP is free software available at http://www.php.net/software/ +- // +- // notes: +- // - IDL does not support IPv6 URLs, GDL does +- // - IDL includes characters after '#' in the QUERY part, GDL +- // just skips them and issues a warning (perhaps not needed) +- // - IDL preserves controll characters in URLs, GDL preserves +- // them as well but a warning is issued +- // - IDL sets 80 as a default value for PORT, even if the url has +- // an ftp:// schema indicated - GDL does not have any default value +- // - IDL excludes the leading "/" from the path, GDL preserves it +- // ... these differences seem just rational for me but please do change +- // it if IDL-compatibility would be beneficial for any reason here +- +- BaseGDL* parse_url(EnvT* env) +- { +- // sanity check for number of parameters +- SizeT nParam = env->NParam(); +- +- // 1-nd argument : the url string +- DString url; +- env->AssureScalarPar(0, url); +- +- // sanity check for controll characters +- string::iterator it; +- for (it = url.begin(); it < url.end(); it++) if (iscntrl(*it)) +- { +- Warning("PARSE_URL: URL contains a control character"); +- break; +- } +- +- // creating the output anonymous structure +- DStructDesc* urlstru_desc = new DStructDesc("$truct"); +- SpDString aString; +- urlstru_desc->AddTag("SCHEME", &aString); +- static size_t ixSCHEME = 0; +- urlstru_desc->AddTag("USERNAME", &aString); +- urlstru_desc->AddTag("PASSWORD", &aString); +- urlstru_desc->AddTag("HOST", &aString); +- urlstru_desc->AddTag("PORT", &aString); +- static size_t ixPORT = 4; +- urlstru_desc->AddTag("PATH", &aString); +- urlstru_desc->AddTag("QUERY", &aString); +- DStructGDL* urlstru = new DStructGDL(urlstru_desc, dimension()); +- auto_ptr urlstru_guard(urlstru); +- +- // parsing the URL +- char const *str = url.c_str(); +- size_t length = url.length(); +- char port_buf[6]; +- char const *s, *e, *p, *pp, *ue; +- +- s = str; +- ue = s + length; +- +- // parsing scheme +- if ((e = (const char*)memchr(s, ':', length)) && (e - s)) +- { +- // validating scheme +- p = s; +- while (p < e) +- { +- // scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] +- if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') +- { +- if (e + 1 < ue) goto parse_port; +- else goto just_path; +- } +- p++; +- } +- if (*(e + 1) == '\0') +- { +- // only scheme is available +- urlstru->InitTag("SCHEME", DStringGDL(string(s, (e - s)))); +- goto end; +- } +- // schemas without '/' (like mailto: and zlib:) +- if (*(e+1) != '/') +- { +- // check if the data we get is a port this allows us to correctly parse things like a.com:80 +- p = e + 1; +- while (isdigit(*p)) p++; +- if ((*p == '\0' || *p == '/') && (p - e) < 7) goto parse_port; +- urlstru->InitTag("SCHEME", DStringGDL(string(s, (e - s)))); +- length -= ++e - s; +- s = e; +- goto just_path; +- } +- else +- { +- urlstru->InitTag("SCHEME", DStringGDL(string(s, (e - s)))); +- if (*(e+2) == '/') +- { +- s = e + 3; +- if (!strncasecmp("file", +- (*static_cast(urlstru->GetTag(ixSCHEME)))[0].c_str(), +- sizeof("file") +- )) +- { +- if (*(e + 3) == '/') +- { +- // support windows drive letters as in: file:///c:/somedir/file.txt +- if (*(e + 5) == ':') s = e + 4; +- goto nohost; +- } +- } +- } +- else +- { +- if (!strncasecmp("file", +- (*static_cast(urlstru->GetTag(ixSCHEME)))[0].c_str(), +- sizeof("file")) +- ) +- { +- s = e + 1; +- goto nohost; +- } +- else +- { +- length -= ++e - s; +- s = e; +- goto just_path; +- } +- } +- } +- } +- else if (e) +- { +- // no scheme, look for port +- parse_port: +- p = e + 1; +- pp = p; +- while (pp-p < 6 && isdigit(*pp)) pp++; +- if (pp-p < 6 && (*pp == '/' || *pp == '\0')) +- { +- memcpy(port_buf, p, (pp-p)); +- port_buf[pp-p] = '\0'; +- urlstru->InitTag("PORT", DStringGDL(port_buf)); +- } +- else goto just_path; +- } +- else +- { +- just_path: +- ue = s + length; +- goto nohost; +- } +- e = ue; +- if (!(p = (const char*)memchr(s, '/', (ue - s)))) +- { +- if ((p = (const char*)memchr(s, '?', (ue - s)))) e = p; +- else if ((p = (const char*)memchr(s, '#', (ue - s)))) e = p; +- } +- else e = p; +- // check for login and password +- { +- size_t pos; +- if ((pos = string(s, e - s).find_last_of("@")) != string::npos) +- { +- p = s + pos; +- if ((pp = (const char*)memchr(s, ':', (p-s)))) +- { +- if ((pp-s) > 0) urlstru->InitTag("USERNAME", DStringGDL(string(s, (pp - s)))); +- pp++; +- if (p-pp > 0) urlstru->InitTag("PASSWORD", DStringGDL(string(pp, (p - pp)))); +- } +- else urlstru->InitTag("USERNAME", DStringGDL(string(s, (p - s)))); +- s = p + 1; +- } +- } +- // check for port +- if (*s == '[' && *(e-1) == ']') p = s; // IPv6 embedded address +- else for(p = e; *p != ':' && p >= s; p--); // memrchr is a GNU extension +- if (p >= s && *p == ':') +- { +- if ((*static_cast(urlstru->GetTag(ixPORT)))[0].length() == 0) +- { +- p++; +- if (e-p > 5) env->Throw("port cannot be longer then 5 characters"); +- else if (e - p > 0) +- { +- memcpy(port_buf, p, (e-p)); +- port_buf[e-p] = '\0'; +- urlstru->InitTag("PORT", DStringGDL(port_buf)); +- } +- p--; +- } +- } +- else p = e; +- // check if we have a valid host, if we don't reject the string as url +- if ((p-s) < 1) env->Throw("invalid host"); +- urlstru->InitTag("HOST", DStringGDL(string(s, (p - s)))); +- if (e == ue) goto end; +- s = e; +- nohost: +- if ((p = (const char*)memchr(s, '?', (ue - s)))) +- { +- pp = strchr(s, '#'); +- if (pp && pp < p) +- { +- p = pp; +- pp = strchr(pp+2, '#'); +- } +- if (p - s) urlstru->InitTag("PATH", DStringGDL(string(s, (p - s)))); +- if (pp) +- { +- if (pp - ++p) urlstru->InitTag("QUERY", DStringGDL(string(p, (pp - p)))); +- p = pp; +- goto label_parse; +- } +- else if (++p - ue) urlstru->InitTag("QUERY", DStringGDL(string(p, (ue - p)))); +- } +- else if ((p = (const char*)memchr(s, '#', (ue - s)))) +- { +- if (p - s) urlstru->InitTag("PATH", DStringGDL(string(s, (p - s)))); +- label_parse: +- p++; +- if (ue - p) Warning("PARSE_URL: URL fragment left out: #" + string(p, (ue-p))); +- } +- else urlstru->InitTag("PATH", DStringGDL(string(s, (ue - s)))); +- end: +- +- // returning the result +- urlstru_guard.release(); +- return urlstru; +- } +- +- BaseGDL* locale_get(EnvT* e) +- { +-#ifdef HAVE_LOCALE_H +- +- // make GDL inherit the calling process locale +- setlocale(LC_ALL, ""); +- // note doen the inherited locale +- DStringGDL *locale = new DStringGDL(setlocale(LC_CTYPE, NULL)); +- // return to the C locale +- setlocale(LC_ALL, "C"); +- +- return locale; +-#else +- e->Throw("OS does not provide locale information"); +-#endif +- } +- +- // SA: relies on the contents of the lib::command_line_args vector +- // defined and filled with data (pointers) in gdl.cpp +- BaseGDL* command_line_args_fun(EnvT* e) +- { +-#ifdef PYTHON_MODULE +- e->Throw("no command line arguments available (GDL built as a Python module)"); +-#else +- static int countIx = e->KeywordIx("COUNT"); +- extern std::vector command_line_args; +- +- // setting the COUNT keyword value +- if (e->KeywordPresent(countIx)) +- { +- e->AssureGlobalKW(countIx); +- e->SetKW(countIx, new DLongGDL(command_line_args.size())); +- } +- +- // returning empty string or an array of arguments +- if (command_line_args.empty()) return new DStringGDL(""); +- else +- { +- BaseGDL* ret = new DStringGDL(dimension(command_line_args.size())); +- for (size_t i = 0; i < command_line_args.size(); i++) +- (*static_cast(ret))[i] = command_line_args[i]; +- return ret; +- } +-#endif +- } +- +- // SA: relies in the uname() from libc (must be there if POSIX) +- BaseGDL* get_login_info( EnvT* e) +- { +- // getting the info +-#ifdef _MSC_VER +- #define MAX_TCHAR_BUF 256 +- +- char login[MAX_TCHAR_BUF]; +- char info[MAX_TCHAR_BUF]; +- +- DWORD N_TCHAR = MAX_TCHAR_BUF; +- +- #ifdef _UNICODE +- TCHAR t_buf[MAX_TCHAR_BUF]; +- GetUserName(t_buf, &N_TCHAR); +- WideCharToMultiByte(CP_ACP, 0, t_buf, N_TCHAR, login, N_TCHAR, NULL, NULL); +- GetComputerName( t_buf, &N_TCHAR ); +- WideCharToMultiByte(CP_ACP, 0, t_buf, N_TCHAR, info, N_TCHAR, NULL, NULL); +- #else +- GetUserName(login, &N_TCHAR); +- GetComputerName(info, &N_TCHAR); +- #endif +-#else +- char* login = getlogin(); +- if (login == NULL) e->Throw("Failed to get user name from the OS"); +- struct utsname info; +- if (0 != uname(&info)) e->Throw("Failed to get machine name from the OS"); +-#endif +- // creating the output anonymous structure +- DStructDesc* stru_desc = new DStructDesc("$truct"); +- SpDString aString; +- stru_desc->AddTag("MACHINE_NAME", &aString); +- stru_desc->AddTag("USER_NAME", &aString); +- DStructGDL* stru = new DStructGDL(stru_desc, dimension()); +- +- // returning the info +- stru->InitTag("USER_NAME", DStringGDL(login)); +-#ifdef _MSC_VER +- stru->InitTag("MACHINE_NAME", DStringGDL(info)); +-#else +- stru->InitTag("MACHINE_NAME", DStringGDL(info.nodename)); +-#endif +- return stru; +- } +- +- // SA: base64 logic in base64.hpp, based on code by Bob Withers (consult base64.hpp) +- BaseGDL* idl_base64(EnvT* e) +- { +- BaseGDL* p0 = e->GetPar(0); +- if (p0 != NULL) +- { +- if (p0->Rank() == 0 && p0->Type() == GDL_STRING) +- { +- // decoding +- string* str = &((*static_cast(p0))[0]); +- if (str->length() == 0) return new DByteGDL(0); +- if (str->length() % 4 != 0) +- e->Throw("Input string length must be a multiple of 4"); +- unsigned int retlen = base64::decodeSize(*str); +- if (retlen == 0 || retlen > str->length()) e->Throw("No data in the input string"); +- DByteGDL* ret = new DByteGDL(dimension(retlen)); +- if (!base64::decode(*str, (char*)&((*ret)[0]), ret->N_Elements())) +- e->Throw("Base64 decoder failed"); +- return ret; +- } +- if (p0->Rank() >= 1 && p0->Type() == GDL_BYTE) +- { +- // encoding +- return new DStringGDL( +- base64::encode((char*)&(*static_cast(p0))[0], p0->N_Elements()) +- ); +- } +- } +- e->Throw("Expecting string or byte array as a first parameter"); +- } +- +- BaseGDL* get_drive_list(EnvT* e) +- { +- if (e->KeywordPresent(0)) e->SetKW(0, new DLongGDL(0)); +- return new DStringGDL(""); +- } +- +- // note: changes here MUST be reflected in scope_varfetch_reference() as well +- // because DLibFun of this function is used for scope_varfetch_reference() the keyword +- // indices must match +- BaseGDL* scope_varfetch_value( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- +- EnvStackT& callStack = e->Interpreter()->CallStack(); +-// DLong curlevnum = callStack.size()-1; +-// 'e' is not on the stack +- DLong curlevnum = callStack.size(); +- +-// static int variablesIx = e->KeywordIx( "VARIABLES" ); +- static int levelIx = e->KeywordIx( "LEVEL" ); +- +- DLongGDL* level = e->IfDefGetKWAs( levelIx); +- +- DLong desiredlevnum = 0; +- +- if (level != NULL) +- desiredlevnum = (*level)[0]; +- +- if (desiredlevnum <= 0) desiredlevnum += curlevnum; +- if (desiredlevnum < 1) desiredlevnum = 1; +- else if (desiredlevnum > curlevnum) desiredlevnum = curlevnum; +- +- DSubUD* pro = static_cast(callStack[desiredlevnum-1]->GetPro()); +- +- SizeT nVar = pro->Size(); // # var in GDL for desired level +- int nKey = pro->NKey(); +- +- DString varName; +- +- e->AssureScalarPar( 0, varName); +- varName = StrUpCase( varName); +- +- int xI = pro->FindVar( varName); +- if (xI != -1) +- { +-// BaseGDL*& par = ((EnvT*)(callStack[desiredlevnum-1]))->GetPar( xI); +- BaseGDL*& par = callStack[desiredlevnum-1]->GetKW( xI); +- +- if( par == NULL) +- e->Throw( "Variable is undefined: " + varName); +- +- return par->Dup(); +- } +- +- e->Throw( "Variable not found: " + varName); +- return new DLongGDL(0); // compiler shut-up +- } +- +- // this routine is special, only called as an l-function (from FCALL_LIB::LEval()) +- // it MUST use an EnvT set up for scope_varfetch_value +- BaseGDL** scope_varfetch_reference( EnvT* e) +- { +- SizeT nParam=e->NParam(); +- +- EnvStackT& callStack = e->Interpreter()->CallStack(); +-// DLong curlevnum = callStack.size()-1; +-// 'e' is not on the stack +- DLong curlevnum = callStack.size(); +- +-// static int variablesIx = e->KeywordIx( "VARIABLES" ); +- static int levelIx = e->KeywordIx( "LEVEL" ); +- +- DLongGDL* level = e->IfDefGetKWAs( levelIx); +- +- DLong desiredlevnum = 0; +- +- if (level != NULL) +- desiredlevnum = (*level)[0]; +- +- if (desiredlevnum <= 0) desiredlevnum += curlevnum; +- if (desiredlevnum < 1) desiredlevnum = 1; +- else if (desiredlevnum > curlevnum) desiredlevnum = curlevnum; +- +- DSubUD* pro = static_cast(callStack[desiredlevnum-1]->GetPro()); +- +- SizeT nVar = pro->Size(); // # var in GDL for desired level +- int nKey = pro->NKey(); +- +- DString varName; +- +- e->AssureScalarPar( 0, varName); +- varName = StrUpCase( varName); +- int xI = pro->FindVar( varName); +- if (xI != -1) +- { +-// BaseGDL*& par = ((EnvT*)(callStack[desiredlevnum-1]))->GetPar( xI); +- BaseGDL*& par = callStack[desiredlevnum-1]->GetKW( xI); +- +-// if( par == NULL) +-// e->Throw( "Variable is undefined: " + varName); +- +- return ∥ +- } +- +- e->Throw( "LVariable not found: " + varName); +- return NULL; // compiler shut-up +- } +- +- +-} // namespace +- ++/*************************************************************************** ++ basic_fun.cpp - basic GDL library function ++ ------------------- ++ begin : July 22 2002 ++ copyright : (C) 2002 by Marc Schellens (exceptions see below) ++ email : m_schellens@users.sf.net ++ ++ strtok_fun, getenv_fun, tag_names_fun, stregex_fun: ++ (C) 2004 by Peter Messmer ++ ++***************************************************************************/ ++ ++/*************************************************************************** ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ ***************************************************************************/ ++ ++#include "includefirst.hpp" ++ ++// get_kbrd patch ++// http://sourceforge.net/forum/forum.php?thread_id=3292183&forum_id=338691 ++#ifndef _MSC_VER ++#include ++#include ++#endif ++#include ++#include ++#include ++//#include ++#include // stregex ++ ++#ifdef __APPLE__ ++# include ++# define environ (*_NSGetEnviron()) ++#endif ++ ++#if defined(__FreeBSD__) || defined(__sun__) || defined(__OpenBSD__) ++extern "C" char **environ; ++#endif ++ ++#include "nullgdl.hpp" ++#include "datatypes.hpp" ++#include "envt.hpp" ++#include "dpro.hpp" ++#include "dinterpreter.hpp" ++#include "basic_pro.hpp" ++#include "terminfo.hpp" ++#include "typedefs.hpp" ++#include "base64.hpp" ++ ++#ifdef HAVE_LOCALE_H ++# include ++#endif ++ ++/* max regexp error message length */ ++#define MAX_REGEXPERR_LENGTH 80 ++ ++#ifdef _MSC_VER ++#define isfinite _finite ++#define isnan _isnan ++#define round(f) floor(f+0.5) ++int strncasecmp(const char *s1, const char *s2, size_t n) ++{ ++ if (n == 0) ++ return 0; ++ while (n-- != 0 && tolower(*s1) == tolower(*s2)) ++ { ++ if (n == 0 || *s1 == '\0' || *s2 == '\0') ++ break; ++ s1++; ++ s2++; ++ } ++ ++ return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); ++} ++#else ++#include ++#endif ++ ++namespace lib { ++ ++ using namespace std; ++ using namespace antlr; ++ ++ // assumes all parameters from pOffs till end are dim ++ void arr( EnvT* e, dimension& dim, SizeT pOffs=0) ++ { ++ ++ int nParam=e->NParam()-pOffs; ++ ++ if( nParam <= 0) ++ e->Throw( "Incorrect number of arguments."); ++ ++ const string BadDims="Array dimensions must be greater than 0."; ++ ++ ++ if( nParam == 1 ) { ++ ++ BaseGDL* par = e->GetParDefined( pOffs); ++ ++ SizeT newDim; ++ int ret = par->Scalar2index( newDim); ++ ++ if (ret < 0) throw GDLException(BadDims); ++ ++ if( ret > 0) { // single argument ++ if (newDim < 1) throw GDLException(BadDims); ++ dim << newDim; ++ return; ++ } ++ if( ret == 0) { // array argument ++ DLongGDL* ind = ++ static_cast(par->Convert2(GDL_LONG, BaseGDL::COPY)); ++ auto_ptr ind_guard( ind); ++ //e->Guard( ind); ++ ++ for(SizeT i =0; i < par->N_Elements(); ++i){ ++ if ((*ind)[i] < 1) throw GDLException(BadDims); ++ dim << (*ind)[i]; ++ } ++ return; ++ } ++ e->Throw( "arr: should never arrive here."); ++ return; ++ } ++ ++ // max number checked in interpreter ++ SizeT endIx=nParam+pOffs; ++ for( SizeT i=pOffs; iGetParDefined( i); ++ ++ SizeT newDim; ++ int ret=par->Scalar2index( newDim); ++ if( ret < 1 || newDim == 0) throw GDLException(BadDims); ++ dim << newDim; ++ } ++ } ++ ++ BaseGDL* bytarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DByteGDL(dim, BaseGDL::NOZERO); ++ return new DByteGDL(dim); ++ // } ++ // catch( GDLException& ex) ++ // { ++// e->Throw( ex.getMessage()); ++// } ++ } ++ BaseGDL* intarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DIntGDL(dim, BaseGDL::NOZERO); ++ return new DIntGDL(dim); ++// } ++// catch( GDLException& ex) ++// { ++// e->Throw( "INTARR: "+ex.getMessage()); ++// } ++ } ++ BaseGDL* uintarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DUIntGDL(dim, BaseGDL::NOZERO); ++ return new DUIntGDL(dim); ++// } ++// catch( GDLException& ex) ++// { ++// e->Throw( "UINTARR: "+ex.getMessage()); ++// } ++ } ++ BaseGDL* lonarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DLongGDL(dim, BaseGDL::NOZERO); ++ return new DLongGDL(dim); ++/* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "LONARR: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* ulonarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DULongGDL(dim, BaseGDL::NOZERO); ++ return new DULongGDL(dim); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "ULONARR: "+ex.getMessage()); ++ } ++ */ ++} ++ BaseGDL* lon64arr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DLong64GDL(dim, BaseGDL::NOZERO); ++ return new DLong64GDL(dim); ++/* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "LON64ARR: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* ulon64arr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DULong64GDL(dim, BaseGDL::NOZERO); ++ return new DULong64GDL(dim); ++/* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "ULON64ARR: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* fltarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DFloatGDL(dim, BaseGDL::NOZERO); ++ return new DFloatGDL(dim); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "FLTARR: "+ex.getMessage()); ++ } ++ */} ++ BaseGDL* dblarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DDoubleGDL(dim, BaseGDL::NOZERO); ++ return new DDoubleGDL(dim); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "DBLARR: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* strarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) ++ e->Throw( "Keyword parameters not allowed in call."); ++ return new DStringGDL(dim); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "STRARR: "+ex.getMessage()); ++ } ++ */ } ++ BaseGDL* complexarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ if( e->KeywordSet(0)) return new DComplexGDL(dim, BaseGDL::NOZERO); ++ return new DComplexGDL(dim); ++ /*} ++ catch( GDLException& ex) ++ { ++ e->Throw( "COMPLEXARR: "+ex.getMessage()); ++ } ++ */ } ++ BaseGDL* dcomplexarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ ++ if( e->KeywordSet(0)) return new DComplexDblGDL(dim, BaseGDL::NOZERO); ++ return new DComplexDblGDL(dim); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "DCOMPLEXARR: "+ex.getMessage()); ++ } ++ */ } ++ BaseGDL* ptrarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ DPtrGDL* ret; ++ ++// if( e->KeywordSet(0)) ++// ret= new DPtrGDL(dim);//, BaseGDL::NOZERO); ++// else ++// if( e->KeywordSet(1)) ++// ret= new DPtrGDL(dim, BaseGDL::NOZERO); ++// else ++// return new DPtrGDL(dim); ++ if( !e->KeywordSet(1)) ++ return new DPtrGDL(dim); ++ ++ ret= new DPtrGDL(dim, BaseGDL::NOZERO); ++ ++ SizeT nEl=ret->N_Elements(); ++ SizeT sIx=e->NewHeap(nEl); ++// #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++{ ++// #pragma omp for ++ for( SizeT i=0; iThrow( "PTRARR: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* objarr( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++// reference counting if( e->KeywordSet(0)) return new DObjGDL(dim, BaseGDL::NOZERO); ++ return new DObjGDL(dim); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "OBJARR: "+ex.getMessage()); ++ } ++ */ } ++ ++ BaseGDL* ptr_new( EnvT* e) ++ { ++ int nParam=e->NParam(); ++ ++ if( nParam > 0) ++ { ++ // new ptr from undefined variable is allowed as well ++ BaseGDL* p= e->GetPar( 0); ++ if( p == NULL) ++ { ++ DPtr heapID= e->NewHeap(); ++ return new DPtrGDL( heapID); ++ } ++ ++ if( e->KeywordSet(0)) // NO_COPY ++ { ++ BaseGDL** p= &e->GetPar( 0); ++ // if( *p == NULL) ++ // e->Throw( "Parameter undefined: "+ ++ // e->GetParString(0)); ++ ++ DPtr heapID= e->NewHeap( 1, *p); ++ *p=NULL; ++ return new DPtrGDL( heapID); ++ } ++ else ++ { ++ BaseGDL* p= e->GetParDefined( 0); ++ ++ DPtr heapID= e->NewHeap( 1, p->Dup()); ++ return new DPtrGDL( heapID); ++ } ++ } ++ else ++ { ++ if( e->KeywordSet(1)) // ALLOCATE_HEAP ++ { ++ DPtr heapID= e->NewHeap(); ++ return new DPtrGDL( heapID); ++ } ++ else ++ { ++ return new DPtrGDL( 0); // null ptr ++ } ++ } ++ } ++ ++ BaseGDL* ptr_valid( EnvT* e) ++ { ++ int nParam=e->NParam(); ++ ++ if( e->KeywordPresent( 1)) // COUNT ++ { ++ e->SetKW( 1, new DLongGDL( e->Interpreter()->HeapSize())); ++ } ++ ++ if( nParam == 0) ++ { ++ return e->Interpreter()->GetAllHeap(); ++ } ++ ++ BaseGDL* p = e->GetPar( 0); ++ if( p == NULL) ++ { ++ return new DByteGDL( 0); ++ } ++ ++ if( e->KeywordSet( 0)) // CAST ++ { ++ DLongGDL* pL = dynamic_cast( p); ++ auto_ptr pL_guard; ++ if( pL == NULL) ++ { ++ pL = static_cast(p->Convert2(GDL_LONG,BaseGDL::COPY)); ++ pL_guard.reset( pL); ++ } ++ ++ SizeT nEl = pL->N_Elements(); ++ DPtrGDL* ret = new DPtrGDL( pL->Dim()); // zero ++ GDLInterpreter* interpreter = e->Interpreter(); ++ for( SizeT i=0; iPtrValid( (*pL)[ i])) ++ (*ret)[ i] = (*pL)[ i]; ++ } ++ return ret; ++ } ++ ++ DPtrGDL* pPtr = dynamic_cast( p); ++ if( pPtr == NULL) ++ { ++ return new DByteGDL( p->Dim()); // zero ++ } ++ ++ SizeT nEl = pPtr->N_Elements(); ++ DByteGDL* ret = new DByteGDL( pPtr->Dim()); // zero ++ GDLInterpreter* interpreter = e->Interpreter(); ++ for( SizeT i=0; iPtrValid( (*pPtr)[ i])) ++ (*ret)[ i] = 1; ++ } ++ return ret; ++ } ++ ++ BaseGDL* obj_valid( EnvT* e) ++ { ++ int nParam=e->NParam(); ++ ++ if( e->KeywordPresent( 1)) // COUNT ++ { ++ e->SetKW( 1, new DLongGDL( e->Interpreter()->ObjHeapSize())); ++ } ++ ++ if( nParam == 0) ++ { ++ return e->Interpreter()->GetAllObjHeap(); ++ } ++ ++ BaseGDL* p = e->GetPar( 0); ++ if( p == NULL) ++ { ++ return new DByteGDL( 0); ++ } ++ ++ if( e->KeywordSet( 0)) // CAST ++ { ++ DLongGDL* pL = dynamic_cast( p); ++ auto_ptr pL_guard; ++ if( pL == NULL) ++ { ++ pL = static_cast(p->Convert2(GDL_LONG,BaseGDL::COPY)); ++ pL_guard.reset( pL); ++ // e->Guard( pL); ++ } ++ ++ SizeT nEl = pL->N_Elements(); ++ DObjGDL* ret = new DObjGDL( pL->Dim()); // zero ++ GDLInterpreter* interpreter = e->Interpreter(); ++ for( SizeT i=0; iObjValid( (*pL)[ i])) ++ (*ret)[ i] = (*pL)[ i]; ++ } ++ return ret; ++ } ++ ++ DObjGDL* pObj = dynamic_cast( p); ++ if( pObj == NULL) ++ { ++ return new DByteGDL( p->Dim()); // zero ++ } ++ ++ SizeT nEl = pObj->N_Elements(); ++ DByteGDL* ret = new DByteGDL( pObj->Dim()); // zero ++ GDLInterpreter* interpreter = e->Interpreter(); ++ for( SizeT i=0; iObjValid( (*pObj)[ i])) ++ (*ret)[ i] = 1; ++ } ++ return ret; ++ } ++ ++ BaseGDL* obj_new( EnvT* e) ++ { ++ StackGuard guard( e->Interpreter()->CallStack()); ++ ++ int nParam=e->NParam(); ++ ++ if( nParam == 0) ++ { ++ return new DObjGDL( 0); ++ } ++ ++ DString objName; ++ e->AssureScalarPar( 0, objName); ++ ++ // this is a struct name -> convert to UPPERCASE ++ objName=StrUpCase(objName); ++ if( objName == "IDL_OBJECT") ++ objName = GDL_OBJECT_NAME; // replacement also done in GDLParser ++ ++ DStructDesc* objDesc=e->Interpreter()->GetStruct( objName, e->CallingNode()); ++ ++ DStructGDL* objStruct= new DStructGDL( objDesc, dimension()); ++ ++ DObj objID= e->NewObjHeap( 1, objStruct); // owns objStruct ++ ++ BaseGDL* newObj = new DObjGDL( objID); // the object ++ ++ try { ++ // call INIT function ++ DFun* objINIT= objDesc->GetFun( "INIT"); ++ if( objINIT != NULL) ++ { ++ // morph to obj environment and push it onto the stack again ++ e->PushNewEnvUD( objINIT, 1, &newObj); ++ ++ BaseGDL* res=e->Interpreter()->call_fun( objINIT->GetTree()); ++ ++ if( res == NULL || (!res->Scalar()) || res->False()) ++ { ++ GDLDelete(res); ++ return new DObjGDL( 0); ++ } ++ GDLDelete(res); ++ } ++ } catch(...) { ++ e->FreeObjHeap( objID); // newObj might be changed ++ GDLDelete(newObj); ++ throw; ++ } ++ ++ return newObj; ++ } ++ ++ BaseGDL* bindgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DByteGDL(dim, BaseGDL::INDGEN); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "BINDGEN: "+ex.getMessage()); ++ } ++ */ } ++ // keywords not supported yet ++ BaseGDL* indgen( EnvT* e) ++ { ++ dimension dim; ++ ++ // Defaulting to GDL_INT ++ DType type = GDL_INT; ++ ++ static int kwIx1 = e->KeywordIx("BYTE"); ++ if (e->KeywordSet(kwIx1)){ type = GDL_BYTE; } ++ ++ static int kwIx2 = e->KeywordIx("COMPLEX"); ++ if (e->KeywordSet(kwIx2)){ type = GDL_COMPLEX; } ++ ++ static int kwIx3 = e->KeywordIx("DCOMPLEX"); ++ if (e->KeywordSet(kwIx3)){ type = GDL_COMPLEXDBL; } ++ ++ static int kwIx4 = e->KeywordIx("DOUBLE"); ++ if (e->KeywordSet(kwIx4)){ type = GDL_DOUBLE; } ++ ++ static int kwIx5 = e->KeywordIx("FLOAT"); ++ if (e->KeywordSet(kwIx5)){ type = GDL_FLOAT; } ++ ++ static int kwIx6 = e->KeywordIx("L64"); ++ if (e->KeywordSet(kwIx6)){ type = GDL_LONG64; } ++ ++ static int kwIx7 = e->KeywordIx("LONG"); ++ if (e->KeywordSet(kwIx7)){ type = GDL_LONG; } ++ ++ static int kwIx8 = e->KeywordIx("STRING"); ++ if (e->KeywordSet(kwIx8)){ type = GDL_STRING; } ++ ++ static int kwIx9 = e->KeywordIx("UINT"); ++ if (e->KeywordSet(kwIx9)){ type = GDL_UINT; } ++ ++ static int kwIx10 = e->KeywordIx("UL64"); ++ if (e->KeywordSet(kwIx10)){ type = GDL_ULONG64; } ++ ++ static int kwIx11 = e->KeywordIx("ULONG"); ++ if (e->KeywordSet(kwIx11)){ type = GDL_ULONG; } ++ ++ /*try ++ {*/ ++ // Seeing if the user passed in a TYPE code ++ static int kwIx12 = e->KeywordIx("TYPE"); ++ if ( e->KeywordPresent(kwIx12)){ ++ DLong temp_long; ++ e->AssureLongScalarKW(kwIx12, temp_long); ++ type = static_cast(temp_long); ++ } ++ ++ arr(e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ switch(type) ++ { ++ case GDL_INT: return new DIntGDL(dim, BaseGDL::INDGEN); ++ case GDL_BYTE: return new DByteGDL(dim, BaseGDL::INDGEN); ++ case GDL_COMPLEX: return new DComplexGDL(dim, BaseGDL::INDGEN); ++ case GDL_COMPLEXDBL: return new DComplexDblGDL(dim, BaseGDL::INDGEN); ++ case GDL_DOUBLE: return new DDoubleGDL(dim, BaseGDL::INDGEN); ++ case GDL_FLOAT: return new DFloatGDL(dim, BaseGDL::INDGEN); ++ case GDL_LONG64: return new DLong64GDL(dim, BaseGDL::INDGEN); ++ case GDL_LONG: return new DLongGDL(dim, BaseGDL::INDGEN); ++ case GDL_STRING: { ++ DULongGDL* iGen = new DULongGDL(dim, BaseGDL::INDGEN); ++ return iGen->Convert2(GDL_STRING); ++ } ++ case GDL_UINT: return new DUIntGDL(dim, BaseGDL::INDGEN); ++ case GDL_ULONG64: return new DULong64GDL(dim, BaseGDL::INDGEN); ++ case GDL_ULONG: return new DULongGDL(dim, BaseGDL::INDGEN); ++ default: ++ e->Throw( "Invalid type code specified."); ++ break; ++ } ++/* } ++ catch( GDLException& ex) ++ { ++ e->Throw( ex.getMessage()); ++ }*/ ++ } ++ ++ BaseGDL* uindgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DUIntGDL(dim, BaseGDL::INDGEN); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "UINDGEN: "+ex.getMessage()); ++ } ++ */ } ++ BaseGDL* sindgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ DULongGDL* iGen = new DULongGDL(dim, BaseGDL::INDGEN); ++ return iGen->Convert2( GDL_STRING); ++/* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "SINDGEN: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* lindgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ return new DLongGDL(dim, BaseGDL::INDGEN); ++/* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "LINDGEN: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* ulindgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DULongGDL(dim, BaseGDL::INDGEN); ++/* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "ULINDGEN: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* l64indgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DLong64GDL(dim, BaseGDL::INDGEN); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "L64INDGEN: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* ul64indgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DULong64GDL(dim, BaseGDL::INDGEN); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "UL64INDGEN: "+ex.getMessage()); ++ } ++ */ } ++ BaseGDL* findgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DFloatGDL(dim, BaseGDL::INDGEN); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "FINDGEN: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* dindgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DDoubleGDL(dim, BaseGDL::INDGEN); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "DINDGEN: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* cindgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DComplexGDL(dim, BaseGDL::INDGEN); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "CINDGEN: "+ex.getMessage()); ++ }*/ ++ } ++ BaseGDL* dcindgen( EnvT* e) ++ { ++ dimension dim; ++// try{ ++ arr( e, dim); ++ if (dim[0] == 0) ++ throw GDLException( "Array dimensions must be greater than 0"); ++ ++ return new DComplexDblGDL(dim, BaseGDL::INDGEN); ++ /* } ++ catch( GDLException& ex) ++ { ++ e->Throw( "DCINDGEN: "+ex.getMessage()); ++ } ++ */ } ++ ++ // only called from CALL_FUNCTION ++ // otherwise done directly in FCALL_LIB_N_ELEMENTSNode::Eval(); ++ // (but must be defined anyway for LibInit() for correct parametrization) ++ // N_ELEMENTS is special because on error it just returns 0L ++ // (the error is just caught and dropped) ++ BaseGDL* n_elements( EnvT* e) ++ { ++ SizeT nParam=e->NParam(1); ++ ++ BaseGDL* p0=e->GetPar( 0); ++ ++ if( p0 == NULL) return new DLongGDL( 0); ++ return new DLongGDL( p0->N_Elements()); ++ ++// assert( 0); ++// e->Throw("Internal error: lib::n_elements called."); ++// return NULL; // get rid of compiler warning ++ } ++ ++ template< typename ComplexGDL, typename Complex, typename Float> ++ BaseGDL* complex_fun_template( EnvT* e) ++ { ++ SizeT nParam=e->NParam( 1); ++ if( nParam <= 2) ++ { ++ if( nParam == 2) ++ { ++ BaseGDL* p0=e->GetParDefined( 0); ++ BaseGDL* p1=e->GetParDefined( 1); ++ auto_ptr p0Float( static_cast ++ (p0->Convert2( Float::t,BaseGDL::COPY))); ++ auto_ptr p1Float( static_cast ++ (p1->Convert2( Float::t,BaseGDL::COPY))); ++ if( p0Float->Rank() == 0) ++ { ++ ComplexGDL* res = new ComplexGDL( p1Float->Dim(), ++ BaseGDL::NOZERO); ++ ++ SizeT nE=p1Float->N_Elements(); ++// #pragma omp parallel if (nE >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nE)) ++{ ++// #pragma omp for ++ for( SizeT i=0; iRank() == 0) ++ { ++ ComplexGDL* res = new ComplexGDL( p0Float->Dim(), ++ BaseGDL::NOZERO); ++ ++ SizeT nE=p0Float->N_Elements(); ++// #pragma omp parallel if (nE >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nE)) ++{ ++// #pragma omp for ++ for( SizeT i=0; iN_Elements() >= p1Float->N_Elements()) ++ { ++ ComplexGDL* res = new ComplexGDL( p1Float->Dim(), ++ BaseGDL::NOZERO); ++ ++ SizeT nE=p1Float->N_Elements(); ++// #pragma omp parallel if (nE >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nE)) ++{ ++// #pragma omp for ++ for( SizeT i=0; iDim(), ++ BaseGDL::NOZERO); ++ ++ SizeT nE=p0Float->N_Elements(); ++// #pragma omp parallel if (nE >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nE)) ++{ ++// #pragma omp for ++ for( SizeT i=0; iGetParDefined( 0); ++ if (ComplexGDL::t == p0->Type() && e->GlobalPar(0)) return p0; ++ return p0->Convert2( ComplexGDL::t, BaseGDL::COPY); ++ } ++ } ++ else // GDL_COMPLEX( expr, offs, dim1,..,dim8) ++ { ++ BaseGDL* p0 = e->GetParDefined( 0); ++ // *** WRONG: with offs data is converted bytewise ++ auto_ptr p0Float(static_cast ++ (p0->Convert2( Float::t, ++ BaseGDL::COPY))); ++ DLong offs; ++ e->AssureLongScalarPar( 1, offs); ++ ++ dimension dim; ++ arr( e, dim, 2); ++ ++ SizeT nElCreate=dim.NDimElements(); ++ ++ SizeT nElSource=p0->N_Elements(); ++ ++ if( (offs+2*nElCreate) > nElSource) ++ e->Throw( "Specified offset to" ++ " array is out of range: "+e->GetParString(0)); ++ ++ ComplexGDL* res=new ComplexGDL( dim, BaseGDL::NOZERO); ++ ++// #pragma omp parallel if (nElCreate >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nElCreate)) ++{ ++// #pragma omp for ++ for( SizeT i=0; iKeywordSet("DOUBLE")) { ++ return complex_fun_template< DComplexDblGDL, DComplexDbl, DDoubleGDL>( e); ++ } else { ++ return complex_fun_template< DComplexGDL, DComplex, DFloatGDL>( e); ++ } ++} ++BaseGDL* dcomplex_fun( EnvT* e) ++{ ++ return complex_fun_template< DComplexDblGDL, DComplexDbl, DDoubleGDL>( e); ++} ++ ++ template< class TargetClass> ++ BaseGDL* type_fun( EnvT* e) ++ { ++ SizeT nParam=e->NParam(1); ++ ++ if( nParam == 1) ++ { ++ BaseGDL* p0=e->GetParDefined( 0); ++ ++ assert( dynamic_cast< EnvUDT*>( e->Caller()) != NULL); ++ ++ // type_fun( expr) just convert ++ if( static_cast< EnvUDT*>( e->Caller())->GetIOError() != NULL) ++ return p0->Convert2( TargetClass::t, ++ BaseGDL::COPY_THROWIOERROR); ++ // SA: see tracker item no. 3151760 ++ else if (TargetClass::t == p0->Type() && e->GlobalPar(0)) ++ return p0; ++ else ++ return p0->Convert2( TargetClass::t, BaseGDL::COPY); ++ } ++ ++ BaseGDL* p0=e->GetNumericParDefined( 0); ++ ++ // GDL_BYTE( expr, offs, dim1,..,dim8) ++ DLong offs; ++ e->AssureLongScalarPar( 1, offs); ++ ++ dimension dim; ++ ++ if( nParam > 2) ++ arr( e, dim, 2); ++ ++ TargetClass* res=new TargetClass( dim, BaseGDL::NOZERO); ++ ++ SizeT nByteCreate=res->NBytes(); // net size of new data ++ ++ SizeT nByteSource=p0->NBytes(); // net size of src ++ ++ if( offs < 0 || (offs+nByteCreate) > nByteSource) ++ { ++ GDLDelete(res); ++ e->Throw( "Specified offset to" ++ " expression is out of range: "+e->GetParString(0)); ++ } ++ ++ //*** POSSIBLE ERROR because of alignment here ++ void* srcAddr = static_cast( static_cast(p0->DataAddr()) + ++ offs); ++ void* dstAddr = static_cast(&(*res)[0]); ++ memcpy( dstAddr, srcAddr, nByteCreate); ++ ++ // char* srcAddr = reinterpret_cast(p0->DataAddr()); ++ // char* dstAddr = reinterpret_cast(&(*res)[0]); ++ // copy( srcAddr, srcAddr+nByteCreate, dstAddr); ++ ++ return res; ++ } ++ ++ BaseGDL* byte_fun( EnvT* e) ++ { ++ return type_fun( e); ++ } ++ BaseGDL* uint_fun( EnvT* e) ++ { ++ return type_fun( e); ++ } ++ BaseGDL* long_fun( EnvT* e) ++ { ++ return type_fun( e); ++ } ++ BaseGDL* ulong_fun( EnvT* e) ++ { ++ return type_fun( e); ++ } ++ BaseGDL* long64_fun( EnvT* e) ++ { ++ return type_fun( e); ++ } ++ BaseGDL* ulong64_fun( EnvT* e) ++ { ++ return type_fun( e); ++ } ++ BaseGDL* float_fun( EnvT* e) ++ { ++ return type_fun( e); ++ } ++ BaseGDL* double_fun( EnvT* e) ++ { ++ return type_fun( e); ++ } ++ // GDL_STRING function behaves different ++ BaseGDL* string_fun( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ ++ if( nParam == 0) ++ e->Throw( "Incorrect number of arguments."); ++ ++ bool printKey = e->KeywordSet( 4); ++ int parOffset = 0; ++ ++ // SA: handling special VMS-compatibility syntax, e.g.: string(1,'$(F)') ++ // (if nor FORMAT neither PRINT defined, >1 parameter, last param is scalar string ++ // which begins with "$(" or "(" but is not "()" then last param [minus "$"] is treated as FORMAT) ++ bool vmshack = false; ++ if (!printKey && (e->GetKW(0) == NULL) && nParam > 1) ++ { ++ vmshack = true; ++ BaseGDL* par = e->GetParDefined(nParam - 1); ++ if (par->Type() == GDL_STRING && par->Scalar()) ++ { ++ int dollar = (*static_cast(par))[0].compare(0,2,"$("); ++ if (dollar == 0 || ((*static_cast(par))[0].compare(0,1,"(") == 0 && (*static_cast(par))[0] != "()")) ++ { ++ e->SetKeyword("FORMAT", new DStringGDL( ++ (*static_cast(par))[0].c_str() + (dollar == 0 ? 1 : 0) ++ )); ++ } ++ } ++ } ++ ++ BaseGDL* format_kw = e->GetKW( 0); ++ bool formatKey = format_kw != NULL; ++ ++ if (formatKey && format_kw->Type() == GDL_STRING && (*static_cast(format_kw))[0] == "") formatKey = false; ++ ++ if( printKey || formatKey) // PRINT or FORMAT ++ { ++ stringstream os; ++ ++ SizeT width = 0; ++ if( printKey) // otherwise: FORMAT -> width is ignored ++ { ++ // for /PRINT always a terminal width of 80 is assumed ++ width = 80;//TermWidth(); ++ } ++ ++ if (vmshack) ++ { ++ parOffset = 1; ++ e->ShiftParNumbering(1); ++ } ++ print_os( &os, e, parOffset, width); ++ if (vmshack) ++ { ++ e->ShiftParNumbering(-1); ++ } ++ ++ deque buf; ++ while( os.good()) ++ { ++ string line; ++ getline( os, line); ++ if( os.good()) buf.push_back( line); ++ } ++ ++ SizeT bufSize = buf.size(); ++ if( bufSize == 0) ++ e->Throw( "Internal error: print buffer empty."); ++ ++ if( bufSize > 1) ++ { ++ DStringGDL* retVal = ++ new DStringGDL( dimension( bufSize), BaseGDL::NOZERO); ++ ++ for( SizeT i=0; i conversion ++ { ++ BaseGDL* p0 = e->GetParDefined( 0); ++ // SA: see tracker item no. 3151760 ++ if (p0->Type() == GDL_STRING && e->GlobalPar(0)) return p0; ++ return p0->Convert2( GDL_STRING, BaseGDL::COPY); ++ } ++ else // concatenation ++ { ++ DString s; ++ for( SizeT i=0; iGetParDefined( i); ++ DStringGDL* sP = static_cast ++ ( p->Convert2(GDL_STRING, ++ BaseGDL::COPY_BYTE_AS_INT)); ++ ++ SizeT nEl = sP->N_Elements(); ++ for( SizeT e=0; eIfDefGetKWAs( 0); ++ if (type != NULL) { ++ int typ = (*type)[0]; ++ if (typ == GDL_BYTE) ++ { ++ // SA: slow yet simple solution using GDL_BYTE->GDL_INT->GDL_BYTE conversion ++ return (e->KeywordSet(1) && e->GetPar(0)->Type() == GDL_STRING) ++ ? type_fun( e)->Convert2(GDL_BYTE, BaseGDL::CONVERT) ++ : type_fun( e); ++ } ++ if (typ == 0 || typ == GDL_INT) return type_fun( e); ++ if (typ == GDL_UINT) return type_fun( e); ++ if (typ == GDL_LONG) return type_fun( e); ++ if (typ == GDL_ULONG) return type_fun( e); ++ if (typ == GDL_LONG64) return type_fun( e); ++ if (typ == GDL_ULONG64) return type_fun( e); ++ if (typ == GDL_FLOAT) return type_fun( e); ++ if (typ == GDL_DOUBLE) return type_fun( e); ++ if (typ == GDL_COMPLEX) return type_fun( e); ++ if (typ == GDL_COMPLEXDBL) return type_fun( e); ++ if (typ == GDL_STRING) ++ { ++ // SA: calling GDL_STRING() with correct parameters ++ static int stringIx = LibFunIx("STRING"); ++ ++ assert( stringIx >= 0); ++ ++ EnvT* newEnv= new EnvT(e, libFunList[stringIx], NULL); ++ ++ auto_ptr guard( newEnv); ++ ++ newEnv->SetNextPar(&e->GetPar(0)); // pass as global ++ if (e->KeywordSet(1) && e->GetPar(0)->Type() == GDL_BYTE) ++ newEnv->SetKeyword("PRINT", new DIntGDL(1)); ++// e->Interpreter()->CallStack().push_back( newEnv); ++ return static_cast(newEnv->GetPro())->Fun()(newEnv); ++ } ++ e->Throw( "Improper TYPE value."); ++ } ++ return type_fun( e); ++ } ++ ++ BaseGDL* call_function( EnvT* e) ++ { ++ int nParam=e->NParam(); ++ if( nParam == 0) ++ e->Throw( "No function specified."); ++ ++ DString callF; ++ e->AssureScalarPar( 0, callF); ++ ++ // this is a function name -> convert to UPPERCASE ++ callF = StrUpCase( callF); ++ ++ // first search library funcedures ++ int funIx=LibFunIx( callF); ++ if( funIx != -1) ++ { ++// e->PushNewEnv( libFunList[ funIx], 1); ++ // make the call ++// EnvT* newEnv = static_cast(e->Interpreter()->CallStack().back()); ++ ++ // handle direct call functions ++ if( libFunList[ funIx]->DirectCall()) ++ { ++ BaseGDL* directCallParameter = e->GetParDefined(1); ++ BaseGDL* res = ++ static_cast(libFunList[ funIx])->FunDirect()(directCallParameter, true /*isReference*/); ++ return res; ++ } ++ else ++ { ++ EnvT* newEnv = e->NewEnv( libFunList[ funIx], 1); ++ auto_ptr guard( newEnv); ++ return static_cast(newEnv->GetPro())->Fun()(newEnv); ++ } ++ } ++ else ++ { ++ // no direct call here ++ ++ StackGuard guard( e->Interpreter()->CallStack()); ++ ++ funIx = GDLInterpreter::GetFunIx( callF); ++ ++ e->PushNewEnvUD( funList[ funIx], 1); ++ ++ // make the call ++ EnvUDT* newEnv = static_cast(e->Interpreter()->CallStack().back()); ++ return e->Interpreter()->call_fun(static_cast(newEnv->GetPro())->GetTree()); ++ } ++ } ++ ++ BaseGDL* call_method_function( EnvT* e) ++ { ++ StackGuard guard( e->Interpreter()->CallStack()); ++ ++ int nParam=e->NParam(); ++ if( nParam < 2) ++ e->Throw( "Name and object reference" ++ " must be specified."); ++ ++ DString callP; ++ e->AssureScalarPar( 0, callP); ++ ++ // this is a procedure name -> convert to UPPERCASE ++ callP = StrUpCase( callP); ++ ++ DStructGDL* oStruct = e->GetObjectPar( 1); ++ ++ DFun* method= oStruct->Desc()->GetFun( callP); ++ ++ if( method == NULL) ++ e->Throw( "Method not found: "+callP); ++// // // /**/ ++ e->PushNewEnvUD( method, 2, &e->GetPar( 1)); ++ ++ // make the call ++ return e->Interpreter()->call_fun( method->GetTree()); ++ } ++ ++ ++ ++ BaseGDL* execute( EnvT* e) ++ { ++ int nParam=e->NParam( 1); ++ ++ bool quietCompile = false; ++ if( nParam == 2) ++ { ++ BaseGDL* p1 = e->GetParDefined( 1); ++ ++ if( !p1->Scalar()) ++ e->Throw( "Expression must be scalar in this context: "+ ++ e->GetParString(1)); ++ ++ quietCompile = p1->True(); ++ } ++ ++ if (e->GetParDefined(0)->Rank() != 0) ++ e->Throw("Expression must be scalar in this context: "+e->GetParString(0)); ++ ++ DString line; ++ e->AssureScalarPar( 0, line); ++ ++ // remove current environment (own one) ++ assert( dynamic_cast(e->Caller()) != NULL); ++ EnvUDT* caller = static_cast(e->Caller()); ++// e->Interpreter()->CallStack().pop_back(); ++ ++// wrong: e is guarded, do not delete it here ++// delete e; ++ ++ istringstream istr(line+"\n"); ++ ++ RefDNode theAST; ++ try { ++ GDLLexer lexer(istr, "", caller->CompileOpt()); ++ GDLParser& parser=lexer.Parser(); ++ ++ parser.interactive(); ++ ++ theAST=parser.getAST(); ++ } ++ catch( GDLException& ex) ++ { ++ if( !quietCompile) GDLInterpreter::ReportCompileError( ex); ++ return new DIntGDL( 0); ++ } ++ catch( ANTLRException ex) ++ { ++ if( !quietCompile) cerr << "EXECUTE: Lexer/Parser exception: " << ++ ex.getMessage() << endl; ++ return new DIntGDL( 0); ++ } ++ ++ if( theAST == NULL) return new DIntGDL( 1); ++ ++ RefDNode trAST; ++ try ++ { ++ GDLTreeParser treeParser( caller); ++ ++ treeParser.interactive(theAST); ++ ++ trAST=treeParser.getAST(); ++ } ++ catch( GDLException& ex) ++ { ++ if( !quietCompile) GDLInterpreter::ReportCompileError( ex); ++ return new DIntGDL( 0); ++ } ++ ++ catch( ANTLRException ex) ++ { ++ if( !quietCompile) cerr << "EXECUTE: Compiler exception: " << ++ ex.getMessage() << endl; ++ return new DIntGDL( 0); ++ } ++ ++ if( trAST == NULL) return new DIntGDL( 1); ++ ++ int nForLoopsIn = caller->NForLoops(); ++ try ++ { ++ ProgNodeP progAST = ProgNode::NewProgNode( trAST); ++ auto_ptr< ProgNode> progAST_guard( progAST); ++ ++ int nForLoops = ProgNode::NumberForLoops( progAST, nForLoopsIn); ++ caller->ResizeForLoops( nForLoops); ++ ++ progAST->setLine( e->GetLineNumber()); ++ ++ RetCode retCode = caller->Interpreter()->execute( progAST); ++ ++ caller->ResizeForLoops( nForLoopsIn); ++ ++ if( retCode == RC_OK) ++ return new DIntGDL( 1); ++ else ++ return new DIntGDL( 0); ++ } ++ catch( GDLException& ex) ++ { ++ caller->ResizeForLoops( nForLoopsIn); ++ // are we throwing to target environment? ++// if( ex.GetTargetEnv() == NULL) ++ if( !quietCompile) cerr << "EXECUTE: " << ++ ex.getMessage() << endl; ++ return new DIntGDL( 0); ++ } ++ catch( ANTLRException ex) ++ { ++ caller->ResizeForLoops( nForLoopsIn); ++ ++ if( !quietCompile) cerr << "EXECUTE: Interpreter exception: " << ++ ex.getMessage() << endl; ++ return new DIntGDL( 0); ++ } ++ ++ return new DIntGDL( 0); // control flow cannot reach here - compiler shut up ++ } ++ ++ BaseGDL* assoc( EnvT* e) ++ { ++ SizeT nParam=e->NParam( 2); ++ ++ DLong lun; ++ e->AssureLongScalarPar( 0, lun); ++ ++ bool stdLun = check_lun( e, lun); ++ if( stdLun) ++ e->Throw( "File unit does not allow" ++ " this operation. Unit: "+i2s( lun)); ++ ++ DLong offset = 0; ++ if( nParam >= 3) e->AssureLongScalarPar( 2, offset); ++ ++ BaseGDL* arr = e->GetParDefined( 1); ++ ++ if( arr->StrictScalar()) ++ e->Throw( "Scalar variable not allowed in this" ++ " context: "+e->GetParString(1)); ++ ++ return arr->AssocVar( lun, offset); ++ } ++ ++ // gdl_ naming because of weired namespace problem in MSVC ++ BaseGDL* gdl_logical_and( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ if( nParam != 2) ++ e->Throw( ++ "Incorrect number of arguments."); ++ ++ BaseGDL* e1=e->GetParDefined( 0);//, "LOGICAL_AND"); ++ BaseGDL* e2=e->GetParDefined( 1);//, "LOGICAL_AND"); ++ ++ ULong nEl1 = e1->N_Elements(); ++ ULong nEl2 = e2->N_Elements(); ++ ++ Data_* res; ++ ++ if( e1->Scalar()) ++ { ++ if( e1->LogTrue(0)) ++ { ++ res= new Data_( e2->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl2; i++) ++ (*res)[i] = e2->LogTrue( i) ? 1 : 0; ++} ++ } ++ else ++ { ++ return new Data_( e2->Dim()); ++ } ++ } ++ else if( e2->Scalar()) ++ { ++ if( e2->LogTrue(0)) ++ { ++ res= new Data_( e1->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl1; i++) ++ (*res)[i] = e1->LogTrue( i) ? 1 : 0; ++} ++ } ++ else ++ { ++ return new Data_( e1->Dim()); ++ } ++ } ++ else if( nEl2 < nEl1) ++ { ++ res= new Data_( e2->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl2; i++) ++ (*res)[i] = (e1->LogTrue( i) && e2->LogTrue( i)) ? 1 : 0; ++} ++ } ++ else // ( nEl2 >= nEl1) ++ { ++ res= new Data_( e1->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl1; i++) ++ (*res)[i] = (e1->LogTrue( i) && e2->LogTrue( i)) ? 1 : 0; ++} ++ } ++ return res; ++ } ++ ++ // gdl_ naming because of weired namespace problem in MSVC ++ BaseGDL* gdl_logical_or( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ if( nParam != 2) ++ e->Throw( ++ "Incorrect number of arguments."); ++ ++ BaseGDL* e1=e->GetParDefined( 0);//, "LOGICAL_OR"); ++ BaseGDL* e2=e->GetParDefined( 1);//, "LOGICAL_OR"); ++ ++ ULong nEl1 = e1->N_Elements(); ++ ULong nEl2 = e2->N_Elements(); ++ ++ Data_* res; ++ ++ if( e1->Scalar()) ++ { ++ if( e1->LogTrue(0)) ++ { ++ res= new Data_( e2->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl2; i++) ++ (*res)[i] = 1; ++} ++ } ++ else ++ { ++ res= new Data_( e2->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl2; i++) ++ (*res)[i] = e2->LogTrue( i) ? 1 : 0; ++} ++ } ++ } ++ else if( e2->Scalar()) ++ { ++ if( e2->LogTrue(0)) ++ { ++ res= new Data_( e1->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl1; i++) ++ (*res)[i] = 1; ++} ++ } ++ else ++ { ++ res= new Data_( e1->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl1; i++) ++ (*res)[i] = e1->LogTrue( i) ? 1 : 0; ++} ++ } ++ } ++ else if( nEl2 < nEl1) ++ { ++ res= new Data_( e2->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl2 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl2)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl2; i++) ++ (*res)[i] = (e1->LogTrue( i) || e2->LogTrue( i)) ? 1 : 0; ++} ++ } ++ else // ( nEl2 >= nEl1) ++ { ++ res= new Data_( e1->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl1; i++) ++ (*res)[i] = (e1->LogTrue( i) || e2->LogTrue( i)) ? 1 : 0; ++} ++ } ++ return res; ++ } ++ ++ BaseGDL* logical_true( BaseGDL* e1, bool isReference)//( EnvT* e); ++ { ++ assert( e1 != NULL); ++ assert( e1->N_Elements() > 0); ++ ++ ++// SizeT nParam=e->NParam(); ++// if( nParam != 1) ++// e->Throw( ++// "Incorrect number of arguments."); ++// ++// BaseGDL* e1=e->GetParDefined( 0);//, "LOGICAL_TRUE"); ++// ++ ULong nEl1 = e1->N_Elements(); ++ ++ Data_* res = new Data_( e1->Dim(), BaseGDL::NOZERO); ++// #pragma omp parallel if (nEl1 >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl1)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i < nEl1; i++) ++ (*res)[i] = e1->LogTrue( i) ? 1 : 0; ++} ++ return res; ++ } ++ ++ BaseGDL* replicate( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ if( nParam < 2) ++ e->Throw( "Incorrect number of arguments."); ++ dimension dim; ++ arr( e, dim, 1); ++ ++ BaseGDL* p0=e->GetParDefined( 0);//, "REPLICATE"); ++ if( !p0->Scalar()) ++ e->Throw( "Expression must be a scalar in this context: "+ ++ e->GetParString(0)); ++ ++ return p0->New( dim, BaseGDL::INIT); ++ } ++ ++ BaseGDL* strtrim( EnvT* e) ++ { ++ SizeT nParam = e->NParam( 1);//, "STRTRIM"); ++ ++ BaseGDL* p0 = e->GetPar( 0); ++ if( p0 == NULL) ++ e->Throw( ++ "Variable is undefined: "+ ++ e->GetParString(0)); ++ DStringGDL* p0S = static_cast ++ (p0->Convert2(GDL_STRING,BaseGDL::COPY)); ++ ++ DLong mode = 0; ++ if( nParam == 2) ++ { ++ BaseGDL* p1 = e->GetPar( 1); ++ if( p1 == NULL) ++ e->Throw( ++ "Variable is undefined: "+e->GetParString(1)); ++ if( !p1->Scalar()) ++ e->Throw( ++ "Expression must be a " ++ "scalar in this context: "+ ++ e->GetParString(1)); ++ DLongGDL* p1L = static_cast ++ (p1->Convert2(GDL_LONG,BaseGDL::COPY)); ++ ++ mode = (*p1L)[ 0]; ++ ++ GDLDelete(p1L); ++ ++ if( mode < 0 || mode > 2) ++ { ++ ostringstream os; ++ p1->ToStream( os); ++ e->Throw( ++ "Value of <"+ p1->TypeStr() + ++ " ("+os.str()+ ++ ")> is out of allowed range."); ++ } ++ } ++ ++ SizeT nEl = p0S->N_Elements(); ++ ++ if( mode == 2) // both ++ { ++TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if ((nEl*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; iNParam( 1); ++ ++ DStringGDL* p0S = e->GetParAs( 0); ++ ++ bool removeAll = e->KeywordSet(0); ++ ++ DStringGDL* res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); ++ ++ SizeT nEl = p0S->N_Elements(); ++TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if ((nEl*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; iNParam( 2);//, "STRPOS"); ++ ++ bool reverseOffset = e->KeywordSet(0); // REVERSE_OFFSET ++ bool reverseSearch = e->KeywordSet(1); // REVERSE_SEARCH ++ ++ DStringGDL* p0S = e->GetParAs( 0); ++ ++ DString searchString; ++ // e->AssureScalarPar( 1, searchString); ++ DStringGDL* sStr = e->GetParAs( 1); ++ if( !sStr->Scalar( searchString)) ++ e->Throw( "Search string must be a scalar or one element array: "+ ++ e->GetParString( 1)); ++ ++ unsigned long pos = string::npos; ++ if( nParam > 2) ++{ ++ BaseGDL* p2 = e->GetParDefined(2); ++// if( p2 != NULL) //e->AssureLongScalarPar( 2,posDLong); ++// { ++ const SizeT pIx = 2; ++ BaseGDL* p = e->GetParDefined( pIx); ++ DLongGDL* lp = static_cast(p->Convert2( GDL_LONG, BaseGDL::COPY)); ++ auto_ptr guard_lp( lp); ++ DLong scalar; ++ if( !lp->Scalar( scalar)) ++ throw GDLException("Parameter must be a scalar in this context: "+ ++ e->GetParString(pIx)); ++ pos = scalar; ++ } ++ ++ DLongGDL* res = new DLongGDL( p0S->Dim(), BaseGDL::NOZERO); ++ ++ SizeT nSrcStr = p0S->N_Elements(); ++TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if ((nSrcStr*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nSrcStr*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; iNParam( 2);//, "STRMID"); ++ ++ bool reverse = e->KeywordSet(0); ++ ++ DStringGDL* p0S = e->GetParAs( 0); ++ DLongGDL* p1L = e->GetParAs( 1); ++ ++ BaseGDL* p2 = e->GetPar( 2); ++ DLongGDL* p2L = NULL; ++ if( p2 != NULL) p2L = e->GetParAs( 2); ++ ++ DLong scVal1; ++ bool sc1 = p1L->Scalar( scVal1); ++ ++ DLong scVal2 = numeric_limits::max(); ++ bool sc2 = true; ++ if( p2L != NULL) ++ { ++ DLong scalar; ++ sc2 = p2L->Scalar( scalar); ++ scVal2 = scalar; ++ } ++ ++ DLong stride; ++ if( !sc1 && !sc2) ++ { ++ stride = p1L->Dim( 0); ++ if( stride != p2L->Dim( 0)) ++ e->Throw( ++ "Starting offset and length arguments " ++ "have incompatible first dimension."); ++ } ++ else ++ { ++ // at least one scalar, p2L possibly NULL ++ if( p2L == NULL) ++ stride = p1L->Dim( 0); ++ else ++ stride = max( p1L->Dim( 0), p2L->Dim( 0)); ++ ++ stride = (stride > 0)? stride : 1; ++ } ++ ++ dimension resDim( p0S->Dim()); ++ if( stride > 1) ++ resDim >> stride; ++ ++ DStringGDL* res = new DStringGDL( resDim, BaseGDL::NOZERO); ++ ++ SizeT nEl1 = p1L->N_Elements(); ++ SizeT nEl2 = (sc2)? 1 : p2L->N_Elements(); ++ ++ SizeT nSrcStr = p0S->N_Elements(); ++TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if ((nSrcStr*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nSrcStr*10))) default( shared) ++{ ++#pragma omp for ++ for( OMPInt i=0; iN_Elements() > 0); ++ ++// e->NParam( 1);//, "STRLOWCASE"); ++ ++// DStringGDL* p0S = e->GetParAs( 0); ++ DStringGDL* p0S; ++ DStringGDL* res; ++// auto_ptr guard; ++ ++ if( p0->Type() == GDL_STRING) ++ { ++ p0S = static_cast( p0); ++ if( !isReference) ++ res = p0S; ++ else ++ res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); ++ } ++ else ++ { ++ p0S = static_cast( p0->Convert2( GDL_STRING, BaseGDL::COPY)); ++ res = p0S; ++// guard.reset( p0S); ++ } ++ ++// DStringGDL* res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); ++ ++ SizeT nEl = p0S->N_Elements(); ++ ++ if( res == p0S) ++ { ++TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if ((nEl*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; iN_Elements() > 0); ++ ++// e->NParam( 1);//, "STRLOWCASE"); ++ ++// DStringGDL* p0S = e->GetParAs( 0); ++ DStringGDL* p0S; ++ DStringGDL* res; ++// auto_ptr guard; ++ ++ if( p0->Type() == GDL_STRING) ++ { ++ p0S = static_cast( p0); ++ if( !isReference) ++ res = p0S; ++ else ++ res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); ++ } ++ else ++ { ++ p0S = static_cast( p0->Convert2( GDL_STRING, BaseGDL::COPY)); ++ res = p0S; ++// guard.reset( p0S); ++ } ++ ++// DStringGDL* res = new DStringGDL( p0S->Dim(), BaseGDL::NOZERO); ++ ++ SizeT nEl = p0S->N_Elements(); ++ ++ if( res == p0S) ++ { ++TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if ((nEl*10) >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= (nEl*10))) ++{ ++#pragma omp for ++ for( OMPInt i=0; iN_Elements() > 0); ++ ++// e->NParam( 1);//, "STRLEN"); ++ ++ DStringGDL* p0S; ++ auto_ptr guard; ++ ++ if( p0->Type() == GDL_STRING) ++ p0S = static_cast( p0); ++ else ++ { ++ p0S = static_cast( p0->Convert2( GDL_STRING, BaseGDL::COPY)); ++ guard.reset( p0S); ++ } ++ ++ DLongGDL* res = new DLongGDL( p0S->Dim(), BaseGDL::NOZERO); ++ ++ SizeT nEl = p0S->N_Elements(); ++// #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++{ ++// #pragma omp for ++ for( SizeT i=0; iNParam( 1); ++ ++ DStringGDL* p0S = e->GetParAs( 0); ++ SizeT nEl = p0S->N_Elements(); ++ ++ DString delim = ""; ++ if( nParam > 1) ++ e->AssureStringScalarPar( 1, delim); ++ ++ bool single = e->KeywordSet( 0); // SINGLE ++ ++ if( single) ++ { ++ DStringGDL* res = new DStringGDL( (*p0S)[0]); ++ DString& scl = (*res)[0]; ++ ++ for( SizeT i=1; iDim()); ++ resDim.Purge(); ++ ++ SizeT stride = resDim.Stride( 1); ++ ++ resDim.Remove( 0); ++ ++ DStringGDL* res = new DStringGDL( resDim, BaseGDL::NOZERO); ++ for( SizeT src=0, dst=0; srcNParam( 1);//, "WHERE"); ++ ++ BaseGDL* p0 = e->GetParDefined( 0);//, "WHERE"); ++ ++ SizeT nEl = p0->N_Elements(); ++ ++ SizeT count; ++ ++ static int nullIx = e->KeywordIx("NULL"); ++ bool nullKW = e->KeywordSet(nullIx); ++ ++ DLong* ixList = p0->Where( e->KeywordPresent( 0), count); ++ ArrayGuard guard( ixList); ++ SizeT nCount = nEl - count; ++ ++ if( e->KeywordPresent( 0)) // COMPLEMENT ++ { ++ if( nCount == 0) ++ { ++ if( nullKW) ++ e->SetKW( 0, NullGDL::GetSingleInstance()); ++ else ++ e->SetKW( 0, new DLongGDL( -1)); ++ } ++ else ++ { ++ DLongGDL* cIxList = new DLongGDL( dimension( &nCount, 1), ++ BaseGDL::NOZERO); ++ ++ SizeT cIx = nEl - 1; ++// #pragma omp parallel if (nCount >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nCount)) ++{ ++// #pragma omp for ++ for( SizeT i=0; iSetKW( 0, cIxList); ++ } ++ } ++ ++ if( e->KeywordPresent( 1)) // NCOMPLEMENT ++ { ++ e->SetKW( 1, new DLongGDL( nCount)); ++ } ++ ++ if( nParam == 2) ++ { ++ e->SetPar( 1, new DLongGDL( count)); ++ } ++ ++ if( count == 0) ++ { ++ if( nullKW) ++ return NullGDL::GetSingleInstance(); ++ return new DLongGDL( -1); ++ } ++ ++ return new DLongGDL( ixList, count); ++ ++ // DLongGDL* res = new DLongGDL( dimension( &count, 1), ++ // BaseGDL::NOZERO); ++ // for( SizeT i=0; i(e->Caller()); ++ if( caller == NULL) return new DLongGDL( 0); ++ DLong nP = caller->NParam(); ++ if( caller->IsObject()) ++ return new DLongGDL( nP-1); // "self" is not counted ++ return new DLongGDL( nP); ++ } ++ ++ BaseGDL* keyword_set( EnvT* e) ++ { ++ e->NParam( 1);//, "KEYWORD_SET"); ++ ++ BaseGDL* p0 = e->GetPar( 0); ++ if( p0 == NULL) return new DIntGDL( 0); ++ if( !p0->Scalar()) return new DIntGDL( 1); ++ if( p0->Type() == GDL_STRUCT) return new DIntGDL( 1); ++ if( p0->LogTrue()) return new DIntGDL( 1); ++ return new DIntGDL( 0); ++ } ++ ++ // passing 2nd argument by value is slightly better for float and double, ++ // but incur some overhead for the complex class. ++ template inline void AddOmitNaN(T& dest, T value) ++{ ++ if (isfinite(value)) ++{ ++// #pragma omp atomic ++ dest += value; ++} ++} ++ template inline void AddOmitNaNCpx(T& dest, T value) ++ { ++// #pragma omp atomic ++ dest += T(isfinite(value.real())? value.real() : 0, ++ isfinite(value.imag())? value.imag() : 0); ++ } ++ template<> inline void AddOmitNaN(DComplex& dest, DComplex value) ++ { AddOmitNaNCpx(dest, value); } ++ template<> inline void AddOmitNaN(DComplexDbl& dest, DComplexDbl value) ++ { AddOmitNaNCpx(dest, value); } ++ ++ template inline void NaN2Zero(T& value) ++ { if (!isfinite(value)) value = 0; } ++ template inline void NaN2ZeroCpx(T& value) ++ { ++ value = T(isfinite(value.real())? value.real() : 0, ++ isfinite(value.imag())? value.imag() : 0); ++ } ++ template<> inline void NaN2Zero(DComplex& value) ++ { NaN2ZeroCpx< DComplex>(value); } ++ template<> inline void NaN2Zero(DComplexDbl& value) ++ { NaN2ZeroCpx< DComplexDbl>(value); } ++ ++ // total over all elements ++ template ++ BaseGDL* total_template( T* src, bool omitNaN) ++ { ++ if (!omitNaN) return new T(src->Sum()); ++ typename T::Ty sum = 0; ++ SizeT nEl = src->N_Elements(); ++TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared(sum) ++{ ++#pragma omp for ++ for ( OMPInt i=0; i ++ BaseGDL* total_cu_template( T* res, bool omitNaN) ++ { ++ SizeT nEl = res->N_Elements(); ++ if (omitNaN) ++ { ++// #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++{ ++// #pragma omp for ++ for( SizeT i=0; i ++ BaseGDL* total_over_dim_template( T* src, ++ const dimension& srcDim, ++ SizeT sumDimIx, ++ bool omitNaN) ++ { ++ SizeT nEl = src->N_Elements(); ++ ++ // get dest dim and number of summations ++ dimension destDim = srcDim; ++ SizeT nSum = destDim.Remove( sumDimIx); ++ ++ T* res = new T( destDim); // zero fields ++ ++ // sumStride is also the number of linear src indexing ++ SizeT sumStride = srcDim.Stride( sumDimIx); ++ SizeT outerStride = srcDim.Stride( sumDimIx + 1); ++ SizeT sumLimit = nSum * sumStride; ++ SizeT rIx=0; ++ for( SizeT o=0; o < nEl; o += outerStride) ++ for( SizeT i=0; i < sumStride; ++i) ++ { ++ SizeT oi = o+i; ++ SizeT oiLimit = sumLimit + oi; ++ if( omitNaN) ++ { ++ for( SizeT s=oi; s ++ BaseGDL* total_over_dim_cu_template( T* res, ++ SizeT sumDimIx, ++ bool omitNaN) ++ { ++ SizeT nEl = res->N_Elements(); ++ const dimension& resDim = res->Dim(); ++ if (omitNaN) ++ { ++ for( SizeT i=0; iNParam( 1);//, "TOTAL"); ++ ++ BaseGDL* p0 = e->GetParDefined( 0);//, "TOTAL"); ++ ++ SizeT nEl = p0->N_Elements(); ++ if( nEl == 0) ++ e->Throw( "Variable is undefined: "+e->GetParString(0)); ++ ++ if( p0->Type() == GDL_STRING) ++ e->Throw( "String expression not allowed " ++ "in this context: "+e->GetParString(0)); ++ ++ static int cumIx = e->KeywordIx( "CUMULATIVE"); ++ static int intIx = e->KeywordIx("INTEGER"); ++ static int doubleIx = e->KeywordIx( "DOUBLE"); ++ static int nanIx = e->KeywordIx( "NAN"); ++ static int preserveIx = e->KeywordIx( "PRESERVE_TYPE"); ++ ++ bool cumulative = e->KeywordSet( cumIx); ++ bool intRes = e->KeywordSet( intIx); ++ bool doubleRes = e->KeywordSet( doubleIx); ++ bool nan = e->KeywordSet( nanIx); ++ bool preserve = e->KeywordSet( preserveIx); ++ ++ DLong sumDim = 0; ++ if( nParam == 2) ++ e->AssureLongScalarPar( 1, sumDim); ++ ++ if( sumDim == 0) ++ { ++ if( !cumulative) ++ { ++ if (preserve) ++ { ++ switch (p0->Type()) ++ { ++ case GDL_BYTE: return total_template(static_cast(p0), false); ++ case GDL_INT: return total_template(static_cast(p0), false); ++ case GDL_UINT: return total_template(static_cast(p0), false); ++ case GDL_LONG: return total_template(static_cast(p0), false); ++ case GDL_ULONG: return total_template(static_cast(p0), false); ++ case GDL_LONG64: return total_template(static_cast(p0), false); ++ case GDL_ULONG64: return total_template(static_cast(p0), false); ++ case GDL_FLOAT: return total_template(static_cast(p0), nan); ++ case GDL_DOUBLE: return total_template(static_cast(p0), nan); ++ case GDL_COMPLEX: return total_template(static_cast(p0), nan); ++ case GDL_COMPLEXDBL: return total_template(static_cast(p0), nan); ++ default: assert(false); ++ } ++ } ++ ++ // Integer parts by Erin Sheldon ++ // In IDL total(), the INTEGER keyword takes precedence ++ if( intRes ) ++ { ++ // We use GDL_LONG64 unless the input is GDL_ULONG64 ++ if ( p0->Type() == GDL_LONG64 ) ++ { ++ return total_template ++ ( static_cast(p0), nan ); ++ } ++ if ( p0->Type() == GDL_ULONG64 ) ++ { ++ return total_template ++ ( static_cast(p0), nan ); ++ } ++ ++ // Conver to Long64 ++ DLong64GDL* p0L64 = static_cast ++ (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); ++ auto_ptr guard( p0L64); ++ return total_template( p0L64, nan); ++ ++ } // integer results ++ ++ ++ if( p0->Type() == GDL_DOUBLE) ++ { ++ return total_template ++ ( static_cast(p0), nan); ++ } ++ if( p0->Type() == GDL_COMPLEXDBL) ++ { ++ return total_template ++ ( static_cast(p0), nan); ++ } ++ ++ if( !doubleRes) ++ { ++ if( p0->Type() == GDL_FLOAT) ++ { ++ return total_template ++ ( static_cast(p0), nan); ++ } ++ if( p0->Type() == GDL_COMPLEX) ++ { ++ return total_template ++ ( static_cast(p0), nan); ++ } ++ DFloatGDL* p0F = static_cast ++ (p0->Convert2( GDL_FLOAT,BaseGDL::COPY)); ++ auto_ptr guard( p0F); ++ return total_template( p0F, false); ++ } ++ if( p0->Type() == GDL_COMPLEX) ++ { ++ DComplexDblGDL* p0D = static_cast ++ (p0->Convert2( GDL_COMPLEXDBL,BaseGDL::COPY)); ++ auto_ptr p0D_guard( p0D); ++ return total_template( p0D, nan); ++ } ++ ++ DDoubleGDL* p0D = static_cast ++ (p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)); ++ auto_ptr p0D_guard( p0D); ++ return total_template( p0D, nan); ++ } ++ else // cumulative ++ { ++ if (preserve) ++ { ++ switch (p0->Type()) ++ { ++ case GDL_BYTE: return total_cu_template(static_cast(p0)->Dup(), false); ++ case GDL_INT: return total_cu_template(static_cast(p0)->Dup(), false); ++ case GDL_UINT: return total_cu_template(static_cast(p0)->Dup(), false); ++ case GDL_LONG: return total_cu_template(static_cast(p0)->Dup(), false); ++ case GDL_ULONG: return total_cu_template(static_cast(p0)->Dup(), false); ++ case GDL_LONG64: return total_cu_template(static_cast(p0)->Dup(), false); ++ case GDL_ULONG64: return total_cu_template(static_cast(p0)->Dup(), false); ++ case GDL_FLOAT: return total_cu_template(static_cast(p0)->Dup(), nan); ++ case GDL_DOUBLE: return total_cu_template(static_cast(p0)->Dup(), nan); ++ case GDL_COMPLEX: return total_cu_template(static_cast(p0)->Dup(), nan); ++ case GDL_COMPLEXDBL: return total_cu_template(static_cast(p0)->Dup(), nan); ++ default: assert(false); ++ } ++ } ++ ++ // INTEGER keyword takes precedence ++ if( intRes ) ++ { ++ // We use GDL_LONG64 unless the input is GDL_ULONG64 ++ if ( p0->Type() == GDL_LONG64 ) ++ { ++ return total_cu_template ++ ( static_cast(p0)->Dup(), nan ); ++ } ++ if ( p0->Type() == GDL_ULONG64 ) ++ { ++ return total_cu_template ++ ( static_cast(p0)->Dup(), nan ); ++ } ++ ++ // Convert to Long64 ++ return total_cu_template ++ ( static_cast ++ (p0->Convert2( GDL_LONG64, BaseGDL::COPY)), nan); ++ ++ } // integer results ++ ++ ++ // special case as GDL_DOUBLE type overrides /GDL_DOUBLE ++ if( p0->Type() == GDL_DOUBLE) ++ { ++ return total_cu_template< DDoubleGDL> ++ ( static_cast(p0)->Dup(), nan); ++ } ++ if( p0->Type() == GDL_COMPLEXDBL) ++ { ++ return total_cu_template< DComplexDblGDL> ++ ( static_cast(p0)->Dup(), nan); ++ } ++ ++ ++ ++ if( !doubleRes) ++ { ++ // special case for GDL_FLOAT has no advantage here ++ if( p0->Type() == GDL_COMPLEX) ++ { ++ return total_cu_template< DComplexGDL> ++ ( static_cast(p0)->Dup(), nan); ++ } ++ return total_cu_template< DFloatGDL> ++ ( static_cast( p0->Convert2(GDL_FLOAT, ++ BaseGDL::COPY)), nan); ++ } ++ if( p0->Type() == GDL_COMPLEX) ++ { ++ return total_cu_template< DComplexDblGDL> ++ ( static_cast(p0->Convert2( GDL_COMPLEXDBL, ++ BaseGDL::COPY)), nan); ++ } ++ return total_cu_template< DDoubleGDL> ++ ( static_cast(p0->Convert2( GDL_DOUBLE, ++ BaseGDL::COPY)), nan); ++ } ++ } ++ ++ // total over sumDim ++ dimension srcDim = p0->Dim(); ++ SizeT srcRank = srcDim.Rank(); ++ ++ if( sumDim < 1 || sumDim > srcRank) ++ e->Throw( ++ "Array must have "+i2s(sumDim)+ ++ " dimensions: "+e->GetParString(0)); ++ ++ if( !cumulative) ++ { ++ if (preserve) ++ { ++ switch (p0->Type()) ++ { ++ case GDL_BYTE: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); ++ case GDL_INT: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); ++ case GDL_UINT: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); ++ case GDL_LONG: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); ++ case GDL_ULONG: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); ++ case GDL_LONG64: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); ++ case GDL_ULONG64: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, false); ++ case GDL_FLOAT: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, nan); ++ case GDL_DOUBLE: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, nan); ++ case GDL_COMPLEX: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, nan); ++ case GDL_COMPLEXDBL: return total_over_dim_template(static_cast(p0), srcDim, sumDim-1, nan); ++ default: assert(false); ++ } ++ } ++ ++ // INTEGER keyword takes precedence ++ if( intRes ) ++ { ++ // We use GDL_LONG64 unless the input is GDL_ULONG64 ++ if ( p0->Type() == GDL_LONG64 ) ++ { ++ return total_over_dim_template ++ ( static_cast(p0), srcDim, sumDim-1, nan ); ++ } ++ if ( p0->Type() == GDL_ULONG64 ) ++ { ++ return total_over_dim_template ++ ( static_cast(p0), srcDim, sumDim-1, nan ); ++ } ++ ++ // Conver to Long64 ++ DLong64GDL* p0L64 = static_cast ++ (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); ++ ++ auto_ptr p0L64_guard( p0L64); ++ return total_over_dim_template ++ ( p0L64, srcDim, sumDim-1, nan); ++ ++ } // integer results ++ ++ ++ if( p0->Type() == GDL_DOUBLE) ++ { ++ return total_over_dim_template< DDoubleGDL> ++ ( static_cast(p0), srcDim, sumDim-1, nan); ++ } ++ if( p0->Type() == GDL_COMPLEXDBL) ++ { ++ return total_over_dim_template< DComplexDblGDL> ++ ( static_cast(p0), srcDim, sumDim-1, nan); ++ } ++ if( !doubleRes) ++ { ++ if( p0->Type() == GDL_FLOAT) ++ { ++ return total_over_dim_template< DFloatGDL> ++ ( static_cast(p0), srcDim, sumDim-1, nan); ++ } ++ if( p0->Type() == GDL_COMPLEX) ++ { ++ return total_over_dim_template< DComplexGDL> ++ ( static_cast(p0), srcDim, sumDim-1, nan); ++ } ++ // default for NOT /GDL_DOUBLE ++ DFloatGDL* p0F = static_cast ++ (p0->Convert2( GDL_FLOAT,BaseGDL::COPY)); ++ auto_ptr p0F_guard( p0F); ++ // p0F_guard.reset( p0F); ++ return total_over_dim_template< DFloatGDL> ++ ( p0F, srcDim, sumDim-1, false); ++ } ++ if( p0->Type() == GDL_COMPLEX) ++ { ++ DComplexDblGDL* p0D = static_cast ++ (p0->Convert2( GDL_COMPLEXDBL,BaseGDL::COPY)); ++ auto_ptr p0D_guard( p0D); ++ // p0D_guard.reset( p0D); ++ return total_over_dim_template< DComplexDblGDL> ++ ( p0D, srcDim, sumDim-1, nan); ++ } ++ // default for /GDL_DOUBLE ++ DDoubleGDL* p0D = static_cast ++ (p0->Convert2( GDL_DOUBLE,BaseGDL::COPY)); ++ auto_ptr p0D_guard( p0D); ++ //p0D_guard.reset( p0D); ++ return total_over_dim_template< DDoubleGDL>( p0D, srcDim, sumDim-1,nan); ++ } ++ else // cumulative ++ { ++ if (preserve) ++ { ++ switch (p0->Type()) ++ { ++ case GDL_BYTE: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); ++ case GDL_INT: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); ++ case GDL_UINT: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); ++ case GDL_LONG: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); ++ case GDL_ULONG: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); ++ case GDL_LONG64: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); ++ case GDL_ULONG64: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, false); ++ case GDL_FLOAT: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nan); ++ case GDL_DOUBLE: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nan); ++ case GDL_COMPLEX: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nan); ++ case GDL_COMPLEXDBL: return total_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nan); ++ default: assert(false); ++ } ++ } ++ ++ // INTEGER keyword takes precedence ++ if( intRes ) ++ { ++ // We use GDL_LONG64 unless the input is GDL_ULONG64 ++ if ( p0->Type() == GDL_LONG64 ) ++ { ++ return total_over_dim_cu_template ++ ( static_cast(p0)->Dup(), sumDim-1, nan ); ++ } ++ if ( p0->Type() == GDL_ULONG64 ) ++ { ++ return total_over_dim_cu_template ++ ( static_cast(p0)->Dup(), sumDim-1, nan ); ++ } ++ ++ // Convert to Long64 ++ return total_over_dim_cu_template ++ ( static_cast ++ (p0->Convert2( GDL_LONG64, BaseGDL::COPY)), sumDim-1, nan); ++ ++ } // integer results ++ ++ ++ if( p0->Type() == GDL_DOUBLE) ++ { ++ return total_over_dim_cu_template< DDoubleGDL> ++ ( static_cast(p0)->Dup(), sumDim-1, nan); ++ } ++ if( p0->Type() == GDL_COMPLEXDBL) ++ { ++ return total_over_dim_cu_template< DComplexDblGDL> ++ ( static_cast(p0)->Dup(), sumDim-1, nan); ++ } ++ if( !doubleRes) ++ { ++ // special case for GDL_FLOAT has no advantage here ++ if( p0->Type() == GDL_COMPLEX) ++ { ++ return total_over_dim_cu_template< DComplexGDL> ++ ( static_cast(p0)->Dup(), sumDim-1, nan); ++ } ++ // default for NOT /GDL_DOUBLE ++ return total_over_dim_cu_template< DFloatGDL> ++ ( static_cast( p0->Convert2( GDL_FLOAT, ++ BaseGDL::COPY)), sumDim-1, nan); ++ } ++ if( p0->Type() == GDL_COMPLEX) ++ { ++ return total_over_dim_cu_template< DComplexDblGDL> ++ ( static_cast(p0->Convert2( GDL_COMPLEXDBL, ++ BaseGDL::COPY)), sumDim-1, nan); ++ } ++ // default for /GDL_DOUBLE ++ return total_over_dim_cu_template< DDoubleGDL> ++ ( static_cast(p0->Convert2( GDL_DOUBLE, ++ BaseGDL::COPY)), sumDim-1, nan); ++ } ++ } ++ ++ ++ // passing 2nd argument by value is slightly better for float and double, ++ // but incur some overhead for the complex class. ++ template inline void MultOmitNaN(T& dest, T value) ++ { ++ if (isfinite(value)) ++ { ++// #pragma omp atomic ++ dest *= value; ++ } ++ } ++ template inline void MultOmitNaNCpx(T& dest, T value) ++ { ++ dest *= T(isfinite(value.real())? value.real() : 1, ++ isfinite(value.imag())? value.imag() : 1); ++ } ++ template<> inline void MultOmitNaN(DComplex& dest, DComplex value) ++ { MultOmitNaNCpx(dest, value); } ++ template<> inline void MultOmitNaN(DComplexDbl& dest, DComplexDbl value) ++ { MultOmitNaNCpx(dest, value); } ++ ++ template inline void Nan2One(T& value) ++ { if (!isfinite(value)) value = 1; } ++ template inline void Nan2OneCpx(T& value) ++ { ++ value = T(isfinite(value.real())? value.real() : 1, ++ isfinite(value.imag())? value.imag() : 1); ++ } ++ template<> inline void Nan2One(DComplex& value) ++ { Nan2OneCpx< DComplex>(value); } ++ template<> inline void Nan2One(DComplexDbl& value) ++ { Nan2OneCpx< DComplexDbl>(value); } ++ ++ // product over all elements ++ template ++ BaseGDL* product_template( T* src, bool omitNaN) ++ { ++ typename T::Ty sum = 1; ++ SizeT nEl = src->N_Elements(); ++ if( !omitNaN) ++ { ++TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared(sum) ++{ ++#pragma omp for reduction(*:sum) ++ for ( OMPInt i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared(sum) ++{ ++#pragma omp for reduction(*:sum) ++ for ( OMPInt i=0; i ++ BaseGDL* product_template( DComplexGDL* src, bool omitNaN) ++ { ++ DComplexGDL::Ty sum = 1; ++ SizeT nEl = src->N_Elements(); ++ if( !omitNaN) ++ { ++ for ( SizeT i=0; i ++ BaseGDL* product_template( DComplexDblGDL* src, bool omitNaN) ++ { ++ DComplexDblGDL::Ty sum = 1; ++ SizeT nEl = src->N_Elements(); ++ if( !omitNaN) ++ { ++ for ( SizeT i=0; i ++ BaseGDL* product_cu_template( T* res, bool omitNaN) ++ { ++ SizeT nEl = res->N_Elements(); ++ if( omitNaN) ++ { ++ for( SizeT i=0; i ++ BaseGDL* product_over_dim_template( T* src, ++ const dimension& srcDim, ++ SizeT sumDimIx, ++ bool omitNaN) ++ { ++ SizeT nEl = src->N_Elements(); ++ ++ // get dest dim and number of summations ++ dimension destDim = srcDim; ++ SizeT nSum = destDim.Remove( sumDimIx); ++ ++ T* res = new T( destDim, BaseGDL::NOZERO); ++ ++ // sumStride is also the number of linear src indexing ++ SizeT sumStride = srcDim.Stride( sumDimIx); ++ SizeT outerStride = srcDim.Stride( sumDimIx + 1); ++ SizeT sumLimit = nSum * sumStride; ++ SizeT rIx=0; ++ for( SizeT o=0; o < nEl; o += outerStride) ++ for( SizeT i=0; i < sumStride; ++i) ++ { ++ (*res)[ rIx] = 1; ++ SizeT oi = o+i; ++ SizeT oiLimit = sumLimit + oi; ++ if( omitNaN) ++ { ++ for( SizeT s=oi; s ++ BaseGDL* product_over_dim_cu_template( T* res, ++ SizeT sumDimIx, ++ bool omitNaN) ++ { ++ SizeT nEl = res->N_Elements(); ++ const dimension& resDim = res->Dim(); ++ if (omitNaN) ++ { ++ for( SizeT i=0; iNParam( 1); ++ ++ BaseGDL* p0 = e->GetParDefined( 0); ++ ++ SizeT nEl = p0->N_Elements(); ++ if( nEl == 0) ++ e->Throw( "Variable is undefined: "+e->GetParString(0)); ++ ++ if( p0->Type() == GDL_STRING) ++ e->Throw( "String expression not allowed " ++ "in this context: "+e->GetParString(0)); ++ ++ static int cumIx = e->KeywordIx( "CUMULATIVE"); ++ static int nanIx = e->KeywordIx( "NAN"); ++ static int intIx = e->KeywordIx("INTEGER"); ++ static int preIx = e->KeywordIx("PRESERVE_TYPE"); ++ bool KwCumul = e->KeywordSet( cumIx); ++ bool KwNaN = e->KeywordSet( nanIx); ++ bool KwInt = e->KeywordSet( intIx); ++ bool KwPre = e->KeywordSet( preIx); ++ bool nanInt=false; ++ ++ DLong sumDim = 0; ++ if( nParam == 2) ++ e->AssureLongScalarPar( 1, sumDim); ++ ++ if( sumDim == 0) { ++ if( !KwCumul) { ++ if (KwPre) ++ { ++ switch (p0->Type()) ++ { ++ case GDL_BYTE: return product_template(static_cast(p0), nanInt); ++ case GDL_INT: return product_template(static_cast(p0), nanInt); ++ case GDL_UINT: return product_template(static_cast(p0), nanInt); ++ case GDL_LONG: return product_template(static_cast(p0), nanInt); ++ case GDL_ULONG: return product_template(static_cast(p0), nanInt); ++ case GDL_LONG64: return product_template(static_cast(p0), nanInt); ++ case GDL_ULONG64: return product_template(static_cast(p0), nanInt); ++ case GDL_FLOAT: return product_template(static_cast(p0), KwNaN); ++ case GDL_DOUBLE: return product_template(static_cast(p0), KwNaN); ++ case GDL_COMPLEX: return product_template(static_cast(p0), KwNaN); ++ case GDL_COMPLEXDBL: return product_template(static_cast(p0), KwNaN); ++ default: assert(false); ++ } ++ } ++ ++ // Integer parts derivated from Total code by Erin Sheldon ++ // In IDL PRODUCT(), the INTEGER keyword takes precedence ++ if (KwInt) { ++ // We use GDL_LONG64 unless the input is GDL_ULONG64 ++ if ((p0->Type() == GDL_LONG64) && (!KwNaN)) { ++ return product_template ++ ( static_cast(p0), nanInt ); ++ } ++ if ((p0->Type() == GDL_ULONG64) && (!KwNaN)) { ++ return product_template ++ (static_cast(p0), nanInt ); ++ } ++ ++ // Convert to Long64 ++ DLong64GDL* p0L64 = static_cast ++ (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); ++ auto_ptr guard( p0L64); ++ if (KwNaN) { ++ DFloatGDL* p0f = static_cast ++ (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); ++ auto_ptr guard( p0f); ++ for( SizeT i=0; i( p0L64, nanInt); ++ } // integer results ++ ++ if( p0->Type() == GDL_DOUBLE) { ++ return product_template ++ ( static_cast(p0), KwNaN); ++ } ++ if( p0->Type() == GDL_COMPLEXDBL) { ++ return product_template ++ ( static_cast(p0), KwNaN); ++ } ++ if( p0->Type() == GDL_COMPLEX) { ++ DComplexDblGDL* p0D = static_cast ++ (p0->Convert2( GDL_COMPLEXDBL,BaseGDL::COPY)); ++ auto_ptr p0D_guard( p0D); ++ //p0D_guard.reset( p0D); ++ return product_template( p0D, KwNaN); ++ } ++ ++ DDoubleGDL* p0D = static_cast ++ (p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)); ++ auto_ptr p0D_guard( p0D); ++ // p0D_guard.reset( p0D); ++ return product_template( p0D, KwNaN); ++ } ++ else ++ { // KwCumul ++ ++ if (KwPre) ++ { ++ switch (p0->Type()) ++ { ++ case GDL_BYTE: return product_cu_template(static_cast(p0)->Dup(), nanInt); ++ case GDL_INT: return product_cu_template(static_cast(p0)->Dup(), nanInt); ++ case GDL_UINT: return product_cu_template(static_cast(p0)->Dup(), nanInt); ++ case GDL_LONG: return product_cu_template(static_cast(p0)->Dup(), nanInt); ++ case GDL_ULONG: return product_cu_template(static_cast(p0)->Dup(), nanInt); ++ case GDL_LONG64: return product_cu_template(static_cast(p0)->Dup(), nanInt); ++ case GDL_ULONG64: return product_cu_template(static_cast(p0)->Dup(), nanInt); ++ case GDL_FLOAT: return product_cu_template(static_cast(p0)->Dup(), KwNaN); ++ case GDL_DOUBLE: return product_cu_template(static_cast(p0)->Dup(), KwNaN); ++ case GDL_COMPLEX: return product_cu_template(static_cast(p0)->Dup(), KwNaN); ++ case GDL_COMPLEXDBL: return product_cu_template(static_cast(p0)->Dup(), KwNaN); ++ default: assert(false); ++ } ++ } ++ ++ // Integer parts derivated from Total code by Erin Sheldon ++ // In IDL PRODUCT(), the INTEGER keyword takes precedence ++ if (KwInt) { ++ // We use GDL_LONG64 unless the input is GDL_ULONG64 ++ if ((p0->Type() == GDL_LONG64) && (!KwNaN)) { ++ return product_cu_template ++ ( static_cast(p0)->Dup(), nanInt); ++ } ++ if ((p0->Type() == GDL_ULONG64) && (!KwNaN)) { ++ return product_cu_template ++ ( static_cast(p0)->Dup(), nanInt); ++ } ++ // Convert to Long64 ++ DLong64GDL* p0L64 = static_cast ++ (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); ++ auto_ptr guard( p0L64); ++ if (KwNaN) { ++ DFloatGDL* p0f = static_cast ++ (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); ++ auto_ptr guard( p0f); ++ for( SizeT i=0; i ++ ((p0L64)->Dup(), nanInt); ++ } // integer results ++ ++ // special case as GDL_DOUBLE type overrides /GDL_DOUBLE ++ if (p0->Type() == GDL_DOUBLE) { ++ return product_cu_template< DDoubleGDL> ++ ( static_cast(p0)->Dup(), KwNaN); ++ } ++ if (p0->Type() == GDL_COMPLEXDBL) { ++ return product_cu_template< DComplexDblGDL> ++ ( static_cast(p0)->Dup(), KwNaN); ++ } ++ if (p0->Type() == GDL_COMPLEX) { ++ return product_cu_template< DComplexDblGDL> ++ ( static_cast ++ (p0->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY)), KwNaN); ++ } ++ return product_cu_template< DDoubleGDL> ++ ( static_cast ++ (p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)), KwNaN); ++ } ++ } ++ ++ // product over sumDim ++ dimension srcDim = p0->Dim(); ++ SizeT srcRank = srcDim.Rank(); ++ ++ if( sumDim < 1 || sumDim > srcRank) ++ e->Throw( "Array must have "+i2s(sumDim)+ ++ " dimensions: "+e->GetParString(0)); ++ ++ if (!KwCumul) { ++ ++ if (KwPre) ++ { ++ switch (p0->Type()) ++ { ++ case GDL_BYTE: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); ++ case GDL_INT: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); ++ case GDL_UINT: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); ++ case GDL_LONG: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); ++ case GDL_ULONG: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); ++ case GDL_LONG64: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); ++ case GDL_ULONG64: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, nanInt); ++ case GDL_FLOAT: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, KwNaN); ++ case GDL_DOUBLE: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, KwNaN); ++ case GDL_COMPLEX: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, KwNaN); ++ case GDL_COMPLEXDBL: return product_over_dim_template(static_cast(p0), srcDim, sumDim-1, KwNaN); ++ default: assert(false); ++ } ++ } ++ ++ // Integer parts derivated from Total code by Erin Sheldon ++ // In IDL PRODUCT(), the INTEGER keyword takes precedence ++ if (KwInt) { ++ // We use GDL_LONG64 unless the input is GDL_ULONG64 ++ if ((p0->Type() == GDL_LONG64 ) && (!KwNaN)) { ++ return product_over_dim_template ++ ( static_cast(p0), srcDim, sumDim-1, nanInt); ++ } ++ if ((p0->Type() == GDL_ULONG64) && (!KwNaN)) { ++ return product_over_dim_template ++ ( static_cast(p0), srcDim, sumDim-1, nanInt); ++ } ++ ++ // Conver to Long64 ++ DLong64GDL* p0L64 = static_cast ++ (p0->Convert2( GDL_LONG64, BaseGDL::COPY)); ++ auto_ptr guard( p0L64); ++ if (KwNaN) { ++ DFloatGDL* p0f = static_cast ++ (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); ++ auto_ptr guard( p0f); ++ for( SizeT i=0; i ++ ( p0L64, srcDim, sumDim-1, nanInt); ++ } // integer results ++ ++ if( p0->Type() == GDL_DOUBLE) { ++ return product_over_dim_template< DDoubleGDL> ++ ( static_cast(p0), srcDim, sumDim-1, KwNaN); ++ } ++ if( p0->Type() == GDL_COMPLEXDBL) { ++ return product_over_dim_template< DComplexDblGDL> ++ ( static_cast(p0), srcDim, sumDim-1, KwNaN); ++ } ++ if( p0->Type() == GDL_COMPLEX) { ++ DComplexDblGDL* p0D = static_cast ++ (p0->Convert2( GDL_COMPLEXDBL,BaseGDL::COPY)); ++ auto_ptr p0D_guard( p0D); ++ // p0D_guard.reset( p0D); ++ return product_over_dim_template< DComplexDblGDL> ++ ( p0D, srcDim, sumDim-1, KwNaN); ++ } ++ ++ DDoubleGDL* p0D = static_cast ++ (p0->Convert2( GDL_DOUBLE,BaseGDL::COPY)); ++ auto_ptr p0D_guard( p0D); ++ //p0D_guard.reset( p0D); ++ return product_over_dim_template< DDoubleGDL> ++ ( p0D, srcDim, sumDim-1,KwNaN); ++ } ++ else ++ { // KwCumul ++ ++ if (KwPre) ++ { ++ switch (p0->Type()) ++ { ++ case GDL_BYTE: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); ++ case GDL_INT: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); ++ case GDL_UINT: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); ++ case GDL_LONG: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); ++ case GDL_ULONG: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); ++ case GDL_LONG64: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); ++ case GDL_ULONG64: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, nanInt); ++ case GDL_FLOAT: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, KwNaN); ++ case GDL_DOUBLE: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, KwNaN); ++ case GDL_COMPLEX: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, KwNaN); ++ case GDL_COMPLEXDBL: return product_over_dim_cu_template(static_cast(p0)->Dup(), sumDim-1, KwNaN); ++ default: assert(false); ++ } ++ } ++ ++ // Integer parts derivated from Total code by Erin Sheldon ++ // In IDL PRODUCT(), the INTEGER keyword takes precedence ++ if (KwInt) { ++ // We use GDL_LONG64 unless the input is GDL_ULONG64 ++ if ((p0->Type() == GDL_LONG64) && (!KwNaN)) { ++ return product_over_dim_cu_template ++ ( static_cast(p0)->Dup(), sumDim-1, nanInt); ++ } ++ if ((p0->Type() == GDL_ULONG64 ) && (!KwNaN)) { ++ return product_over_dim_cu_template ++ ( static_cast(p0)->Dup(), sumDim-1, nanInt); ++ } ++ ++ // Convert to Long64 ++ if (KwNaN) { ++ DFloatGDL* p0f = static_cast ++ (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); ++ auto_ptr guard( p0f); ++ for( SizeT i=0; i ++ ( static_cast ++ (p0f->Convert2( GDL_LONG64, BaseGDL::COPY)), sumDim-1, nanInt); ++ } else { ++ return product_over_dim_cu_template ++ ( static_cast ++ (p0->Convert2( GDL_LONG64, BaseGDL::COPY)), sumDim-1, nanInt); ++ } ++ } // integer results ++ ++ if( p0->Type() == GDL_DOUBLE) { ++ return product_over_dim_cu_template< DDoubleGDL> ++ ( static_cast(p0)->Dup(), sumDim-1, KwNaN); ++ } ++ if( p0->Type() == GDL_COMPLEXDBL) { ++ return product_over_dim_cu_template< DComplexDblGDL> ++ ( static_cast(p0)->Dup(), sumDim-1, KwNaN); ++ } ++ if( p0->Type() == GDL_COMPLEX) { ++ return product_over_dim_cu_template< DComplexDblGDL> ++ ( static_cast ++ (p0->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY)), sumDim-1, KwNaN); ++ } ++ ++ return product_over_dim_cu_template< DDoubleGDL> ++ ( static_cast ++ (p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)), sumDim-1, KwNaN); ++ } ++ } ++ ++ BaseGDL* array_equal( EnvT* e) ++ { ++ e->NParam( 2);//, "ARRAY_EQUAL"); ++ ++ BaseGDL* p0 = e->GetParDefined( 0);//, "ARRAY_EQUAL"); ++ BaseGDL* p1 = e->GetParDefined( 1);//, "ARRAY_EQUAL"); ++ ++ if( p0 == p1) return new DByteGDL( 1); ++ ++ SizeT nEl0 = p0->N_Elements(); ++ SizeT nEl1 = p1->N_Elements(); ++ if( nEl0 != nEl1 && nEl0 != 1 && nEl1 != 1) ++ return new DByteGDL( 0); ++ ++ auto_ptr p0_guard; ++ auto_ptr p1_guard; ++ if( p0->Type() != p1->Type()) ++ { ++ if( e->KeywordSet( 0)) // NO_TYPECONV ++ return new DByteGDL( 0); ++ else ++ { ++ DType aTy=p0->Type(); ++ DType bTy=p1->Type(); ++ if( DTypeOrder[aTy] >= DTypeOrder[bTy]) ++ { ++ p1 = p1->Convert2( aTy, BaseGDL::COPY); ++ p1_guard.reset( p1); ++ } ++ else ++ { ++ p0 = p0->Convert2( bTy, BaseGDL::COPY); ++ p0_guard.reset( p0); ++ } ++ } ++ } ++ ++ if( p0->ArrayEqual( p1)) return new DByteGDL( 1); ++ ++ return new DByteGDL( 0); ++ } ++ ++ BaseGDL* min_fun( EnvT* e) ++ { ++ SizeT nParam = e->NParam( 1); ++ BaseGDL* searchArr = e->GetParDefined( 0); ++ ++ bool omitNaN = e->KeywordSet( "NAN"); ++ ++ static int subIx = e->KeywordIx("SUBSCRIPT_MAX"); ++ bool subMax = e->KeywordPresent(subIx); ++ ++ static int dimIx = e->KeywordIx("DIMENSION"); ++ bool dimSet = e->KeywordSet(dimIx); ++ ++ static int maxIx = e->KeywordIx("MAX"); ++ bool maxSet = e->KeywordPresent(maxIx); ++ ++ DLong searchDim; ++ if (dimSet) { ++ e->AssureLongScalarKW(dimIx, searchDim); ++ if (searchDim < 0 || searchDim > searchArr->Rank()) ++ e->Throw("Illegal keyword value for DIMENSION"); ++ } ++ ++ if (dimSet && searchArr->Rank() > 1) ++ { ++ searchDim -= 1; // user-supplied dimensions start with 1! ++ ++ // here destDim is in fact the srcDim... ++ dimension destDim = searchArr->Dim(); ++ SizeT searchStride = destDim.Stride(searchDim); ++ SizeT outerStride = destDim.Stride(searchDim + 1); ++ // ... and now becomes the destDim ++ SizeT nSearch = destDim.Remove(searchDim); ++ SizeT searchLimit = nSearch * searchStride; ++ SizeT nEl = searchArr->N_Elements(); ++ ++ // memory allocation ++ BaseGDL *maxVal, *resArr = searchArr->New(destDim, BaseGDL::NOZERO); ++ DLongGDL *minElArr, *maxElArr; ++ ++ if (maxSet) ++ { ++ e->AssureGlobalKW(maxIx); // instead of using a guard pointer ++ maxVal = searchArr->New(destDim, BaseGDL::NOZERO); ++ } ++ ++ if (subMax) ++ { ++ e->AssureGlobalKW(subIx); // instead of using a guard pointer ++ maxElArr = new DLongGDL(destDim); ++ } ++ ++ if (nParam == 2) ++ { ++ e->AssureGlobalPar(1); // instead of using a guard pointer ++ minElArr = new DLongGDL(destDim); ++ } ++ ++ SizeT rIx = 0; ++ for (SizeT o = 0; o < nEl; o += outerStride) for (SizeT i = 0; i < searchStride; ++i) ++ { ++ searchArr->MinMax( ++ (nParam == 2 ? &((*minElArr)[rIx]) : NULL), ++ (subMax ? &((*maxElArr)[rIx]) : NULL), ++ &resArr, ++ (maxSet ? &maxVal : NULL), ++ omitNaN, o + i, searchLimit + o + i, searchStride, rIx ++ ); ++ rIx++; ++ } ++ ++ if (nParam == 2) e->SetPar(1, minElArr); ++ if (subMax) e->SetKW(subIx, maxElArr); ++ if (maxSet) e->SetKW(maxIx, maxVal); ++ ++ return resArr; ++ } ++ else ++ { ++ DLong minEl; ++ BaseGDL* res; ++ ++ if (maxSet) // MAX keyword given ++ { ++ e->AssureGlobalKW( 0); ++ GDLDelete(e->GetKW( 0)); ++ DLong maxEl; ++ searchArr->MinMax( &minEl, &maxEl, &res, &e->GetKW( 0), omitNaN); ++ if (subMax) e->SetKW(subIx, new DLongGDL(maxEl)); ++ } ++ else // no MAX keyword ++ { ++ if (subMax) ++ { ++ DLong maxEl; ++ searchArr->MinMax( &minEl, &maxEl, &res, NULL, omitNaN); ++ e->SetKW(subIx, new DLongGDL(maxEl)); ++ } ++ else searchArr->MinMax(&minEl, NULL, &res, NULL, omitNaN); ++ } ++ ++ // handle index ++ if (nParam == 2) e->SetPar(1, new DLongGDL( minEl)); ++ else SysVar::SetC( minEl); ++ return res; ++ } ++ } ++ ++ BaseGDL* max_fun( EnvT* e) ++ { ++ SizeT nParam = e->NParam( 1); ++ BaseGDL* searchArr = e->GetParDefined( 0); ++ ++ bool omitNaN = e->KeywordSet( "NAN"); ++ ++ static int subIx = e->KeywordIx("SUBSCRIPT_MIN"); ++ bool subMin = e->KeywordPresent(subIx); ++ ++ static int dimIx = e->KeywordIx("DIMENSION"); ++ bool dimSet = e->KeywordSet(dimIx); ++ ++ static int minIx = e->KeywordIx("MIN"); ++ bool minSet = e->KeywordPresent(minIx); ++ ++ DLong searchDim; ++ if (dimSet) ++ { ++ e->AssureLongScalarKW(dimIx, searchDim); ++ if (searchDim < 0 || searchDim > searchArr->Rank()) ++ e->Throw("Illegal keyword value for DIMENSION"); ++ } ++ ++ if (dimSet && searchArr->Rank() > 1) ++ { ++ searchDim -= 1; // user-supplied dimensions start with 1! ++ ++ // here destDim is in fact the srcDim... ++ dimension destDim = searchArr->Dim(); ++ SizeT searchStride = destDim.Stride(searchDim); ++ SizeT outerStride = destDim.Stride(searchDim + 1); ++ // ... and now becomes the destDim ++ SizeT nSearch = destDim.Remove(searchDim); ++ SizeT searchLimit = nSearch * searchStride; ++ SizeT nEl = searchArr->N_Elements(); ++ ++ // memory allocation ++ BaseGDL *minVal, *resArr = searchArr->New(destDim, BaseGDL::NOZERO); ++ DLongGDL *minElArr, *maxElArr; ++ ++ if (minSet) ++ { ++ e->AssureGlobalKW(minIx); // instead of using a guard pointer ++ minVal = searchArr->New(destDim, BaseGDL::NOZERO); ++ } ++ ++ if (subMin) ++ { ++ e->AssureGlobalKW(subIx); // instead of using a guard pointer ++ minElArr = new DLongGDL(destDim); ++ } ++ ++ if (nParam == 2) ++ { ++ e->AssureGlobalPar(1); // instead of using a guard pointer ++ maxElArr = new DLongGDL(destDim); ++ } ++ ++ SizeT rIx = 0; ++ for (SizeT o = 0; o < nEl; o += outerStride) for (SizeT i = 0; i < searchStride; ++i) ++ { ++ searchArr->MinMax( ++ (subMin ? &((*minElArr)[rIx]) : NULL), ++ (nParam == 2 ? &((*maxElArr)[rIx]) : NULL), ++ (minSet ? &minVal : NULL), ++ &resArr, ++ omitNaN, o + i, searchLimit + o + i, searchStride, rIx ++ ); ++ rIx++; ++ } ++ ++ if (nParam == 2) e->SetPar(1, maxElArr); ++ if (subMin) e->SetKW(subIx, minElArr); ++ if (minSet) e->SetKW(minIx, minVal); ++ ++ return resArr; ++ } ++ else ++ { ++ DLong maxEl; ++ BaseGDL* res; ++ ++ if (minSet) // MIN keyword given ++ { ++ e->AssureGlobalKW( 0); ++ GDLDelete(e->GetKW( 0)); ++ DLong minEl; ++ searchArr->MinMax( &minEl, &maxEl, &e->GetKW( 0), &res, omitNaN); ++ if (subMin) e->SetKW(subIx, new DLongGDL(minEl)); ++ } ++ else // no MIN keyword ++ { ++ if (subMin) ++ { ++ DLong minEl; ++ searchArr->MinMax( &minEl, &maxEl, NULL, &res, omitNaN); ++ e->SetKW(subIx, new DLongGDL(minEl)); ++ } ++ else searchArr->MinMax(NULL, &maxEl, NULL, &res, omitNaN); ++ } ++ ++ // handle index ++ if (nParam == 2) e->SetPar(1, new DLongGDL( maxEl)); ++ else SysVar::SetC(maxEl); ++ return res; ++ } ++ } ++ ++BaseGDL* transpose( EnvT* e) ++ { ++ SizeT nParam=e->NParam( 1); ++ ++ BaseGDL* p0 = e->GetParDefined( 0); ++ if( p0->Type() == GDL_STRUCT) ++ e->Throw("Struct expression not allowed in this context: "+ ++ e->GetParString(0)); ++ ++ SizeT rank = p0->Rank(); ++ if( rank == 0) ++ e->Throw( "Expression must be an array " ++ "in this context: "+ e->GetParString(0)); ++ ++ if( nParam == 2) ++ { ++ ++ BaseGDL* p1 = e->GetParDefined( 1); ++ if( p1->N_Elements() != rank) ++ e->Throw("Incorrect number of elements in permutation."); ++ ++ DUInt* perm = new DUInt[rank]; ++ auto_ptr perm_guard( perm); ++ ++ DUIntGDL* p1L = static_cast ++ (p1->Convert2( GDL_UINT, BaseGDL::COPY)); ++ for( SizeT i=0; iThrow( "Incorrect permutation vector."); ++ } ++ return p0->Transpose( perm); ++ } ++ ++ return p0->Transpose( NULL); ++ } ++ ++ ++// BaseGDL* matrix_multiply( EnvT* e) ++// { ++// SizeT nParam=e->NParam( 2); ++// ++// BaseGDL* a = e->GetNumericArrayParDefined( 0); ++// BaseGDL* b = e->GetNumericArrayParDefined( 1); ++// ++// static int aTIx = e->KeywordIx("ATRANSPOSE"); ++// bool aT = e->KeywordPresent(aTIx); ++// static int bTIx = e->KeywordIx("BTRANSPOSE"); ++// bool bT = e->KeywordPresent(bTIx); ++// ++// static int strassenIx = e->KeywordIx("STRASSEN_ALGORITHM"); ++// bool strassen = e->KeywordPresent(strassenIx); ++// ++// ++// if( p1->N_Elements() != rank) ++// e->Throw("Incorrect number of elements in permutation."); ++// ++// DUInt* perm = new DUInt[rank]; ++// auto_ptr perm_guard( perm); ++// ++// DUIntGDL* p1L = static_cast ++// (p1->Convert2( GDL_UINT, BaseGDL::COPY)); ++// for( SizeT i=0; iThrow( "Incorrect permutation vector."); ++// } ++// return p0->Transpose( perm); ++// } ++// ++// return a->Transpose( NULL); ++// } ++ ++ // helper function for sort_fun, recursive ++ // optimized version ++ template< typename IndexT> ++ void MergeSortOpt( BaseGDL* p0, IndexT* hhS, IndexT* h1, IndexT* h2, ++ SizeT len) ++ { ++ if( len <= 1) return; ++ ++ SizeT h1N = len / 2; ++ SizeT h2N = len - h1N; ++ ++ // 1st half ++ MergeSortOpt(p0, hhS, h1, h2, h1N); ++ ++ // 2nd half ++ IndexT* hhM = &hhS[h1N]; ++ MergeSortOpt(p0, hhM, h1, h2, h2N); ++ ++ SizeT i; ++ for(i=0; iGreater( h1[h1Ix], h2[h2Ix])) ++ hhS[ i] = h2[ h2Ix++]; ++ else ++ hhS[ i] = h1[ h1Ix++]; ++ } ++ for(; h1Ix < h1N; ++i) hhS[ i] = h1[ h1Ix++]; ++ for(; h2Ix < h2N; ++i) hhS[ i] = h2[ h2Ix++]; ++ } ++ ++ // helper function for sort_fun, recursive ++ void MergeSort( BaseGDL* p0, SizeT* hh, SizeT* h1, SizeT* h2, ++ SizeT start, SizeT end) ++ { ++ if( start+1 >= end) return; ++ ++ SizeT middle = (start+end) / 2; ++ ++ MergeSort(p0, hh, h1, h2, start, middle); ++ MergeSort(p0, hh, h1, h2, middle, end); ++ ++ SizeT h1N = middle - start; ++ SizeT h2N = end - middle; ++ ++ SizeT* hhS = &hh[start]; ++ ++ SizeT i; ++ for(i=0; iGreater( h1[h1Ix], h2[h2Ix])) ++ hhS[ i] = h2[ h2Ix++]; ++ else ++ hhS[ i] = h1[ h1Ix++]; ++ } ++ for(; h1Ix < h1N; ++i) hhS[ i] = h1[ h1Ix++]; ++ for(; h2Ix < h2N; ++i) hhS[ i] = h2[ h2Ix++]; ++ } ++ ++ // sort function uses MergeSort ++ BaseGDL* sort_fun( EnvT* e) ++ { ++ e->NParam( 1); ++ ++ BaseGDL* p0 = e->GetParDefined( 0); ++ ++ if( p0->Type() == GDL_STRUCT) ++ e->Throw( "Struct expression not allowed in this context: "+ ++ e->GetParString(0)); ++ ++ static int l64Ix = e->KeywordIx( "L64"); ++ bool l64 = e->KeywordSet( l64Ix); ++ ++ SizeT nEl = p0->N_Elements(); ++ ++ // helper arrays ++ DLongGDL* res = new DLongGDL( dimension( nEl), BaseGDL::INDGEN); ++ ++ DLong nanIx = nEl; ++ if( p0->Type() == GDL_FLOAT) ++ { ++ DFloatGDL* p0F = static_cast(p0); ++ for( DLong i=nEl-1; i >= 0; --i) ++ { ++ if( isnan((*p0F)[ i]) )//|| !isfinite((*p0F)[ i])) ++ { ++ --nanIx; ++ (*res)[i] = (*res)[nanIx]; ++ (*res)[ nanIx] = i; ++ ++// cout << "swap " << i << " with " << nanIx << endl; ++// cout << "now: "; ++// for( DLong ii=0; ii < nEl; ++ii) ++// { ++// cout << (*res)[ii] << " "; ++// } ++// cout << endl; ++ } ++ } ++ } ++ else if( p0->Type() == GDL_DOUBLE) ++ { ++ DDoubleGDL* p0F = static_cast(p0); ++ for( DLong i=nEl-1; i >= 0; --i) ++ { ++ if( isnan((*p0F)[ i]))// || !isfinite((*p0F)[ i])) ++ { ++ --nanIx; ++ (*res)[i] = (*res)[nanIx]; ++ (*res)[ nanIx] = i; ++ } ++ } ++ } ++ else if( p0->Type() == GDL_COMPLEX) ++ { ++ DComplexGDL* p0F = static_cast(p0); ++ for( DLong i=nEl-1; i >= 0; --i) ++ { ++ if( isnan((*p0F)[ i].real()) || //!isfinite((*p0F)[ i].real()) || ++ isnan((*p0F)[ i].imag()))// || !isfinite((*p0F)[ i].imag()) ) ++ { ++ --nanIx; ++ (*res)[i] = (*res)[nanIx]; ++ (*res)[ nanIx] = i; ++ } ++ } ++ } ++ else if( p0->Type() == GDL_COMPLEXDBL) ++ { ++ DComplexDblGDL* p0F = static_cast(p0); ++ for( DLong i=nEl-1; i >= 0; --i) ++ { ++ if( isnan((*p0F)[ i].real()) || //!isfinite((*p0F)[ i].real()) || ++ isnan((*p0F)[ i].imag()))// || !isfinite((*p0F)[ i].imag()) ) ++ { ++ --nanIx; ++ (*res)[i] = (*res)[nanIx]; ++ (*res)[ nanIx] = i; ++ } ++ } ++ } ++ ++// cout << "nEl " << nEl << " nanIx " << nanIx << endl; ++ nEl = nanIx; ++// cout << "sorting: "; ++// for( DLong ii=0; ii < nEl; ++ii) ++// { ++// cout << (*res)[ii] << " "; ++// } ++// cout << endl; ++ ++ DLong *hh = static_cast(res->DataAddr()); ++ ++ DLong* h1 = new DLong[ nEl/2]; ++ DLong* h2 = new DLong[ (nEl+1)/2]; ++ // call the sort routine ++ MergeSortOpt( p0, hh, h1, h2, nEl); ++ delete[] h1; ++ delete[] h2; ++ ++ if( l64) ++ { ++ // leave it this way, as sorting of more than 2^31 ++ // items seems not feasible in the future we might ++ // use MergeSortOpt(...) for this ++ return res->Convert2( GDL_LONG64); ++ } ++ ++ return res; ++ } ++ ++ // uses MergeSort ++ // 2 parts in the code: without "width" or with "width" (limited to 1D and 2D) ++ BaseGDL* median( EnvT* e) { ++ ++ BaseGDL* p0 = e->GetParDefined( 0); ++ ++ if( p0->Type() == GDL_PTR) ++ e->Throw( "Pointer expression not allowed in this context: "+ e->GetParString(0)); ++ if( p0->Type() == GDL_OBJ) ++ e->Throw( "Object expression not allowed in this context: "+ e->GetParString(0)); ++ if( p0->Type() == GDL_STRUCT) ++ e->Throw( "Struct expression not allowed in this context: "+ e->GetParString(0)); ++ ++ if( p0->Rank() == 0) ++ e->Throw( "Expression must be an array in this context: "+ e->GetParString(0)); ++ ++ SizeT nParam = e->NParam( 1); ++ SizeT nEl = p0->N_Elements(); ++ ++ // "f_nan" and "d_nan" used by both parts ... ++ static DStructGDL *Values = SysVar::Values(); ++ DFloat f_nan=(*static_cast(Values->GetTag(Values->Desc()->TagIndex("F_NAN"), 0)))[0]; ++ DDouble d_nan=(*static_cast(Values->GetTag(Values->Desc()->TagIndex("D_NAN"), 0)))[0]; ++ ++ // -------------------------------------------------------- ++ // begin of the part 1: without "width" param ++ if( nParam == 1) { ++ ++ static int evenIx = e->KeywordIx( "EVEN"); ++ ++ // TYPE ++ bool dbl = ++ p0->Type() == GDL_DOUBLE || ++ p0->Type() == GDL_COMPLEXDBL || ++ e->KeywordSet(e->KeywordIx("DOUBLE")); ++ DType type = dbl ? GDL_DOUBLE : GDL_FLOAT; ++ bool noconv = (dbl && p0->Type() == GDL_DOUBLE) || ++ (!dbl && p0->Type() == GDL_FLOAT); ++ ++ // DIMENSION keyword ++ DLong dim = 0; ++ DLong nmed = 1; ++ BaseGDL *res; ++ e->AssureLongScalarKWIfPresent( "DIMENSION", dim); ++ ++ // cout << "dim : "<< dim << endl; ++ ++ if (dim > p0->Rank()) ++ e->Throw( "Illegal keyword value for DIMENSION."); ++ ++ if (dim > 0) { ++ DLong dims[8]; ++ DLong k = 0; ++ for (SizeT i=0; iRank(); ++i) ++ if (i != (dim-1)) { ++ nmed *= p0->Dim(i); ++ dims[k++] = p0->Dim(i); ++ } ++ dimension dimRes((DLong *) dims, p0->Rank()-1); ++ res = dbl ++ ? static_cast(new DDoubleGDL(dimRes, BaseGDL::NOZERO)) ++ : static_cast(new DFloatGDL(dimRes, BaseGDL::NOZERO)); ++ } else { ++ res = dbl ++ ? static_cast(new DDoubleGDL(1)) ++ : static_cast(new DFloatGDL(1)); ++ } ++ ++ // conversion of Complex types ++ if (p0->Type() == GDL_COMPLEX) p0 = p0->Convert2(GDL_FLOAT, BaseGDL::COPY); ++ if (p0->Type() == GDL_COMPLEXDBL) p0 = p0->Convert2(GDL_DOUBLE, BaseGDL::COPY); ++ ++ // helper arrays ++ if (nmed > 1) nEl = p0->N_Elements() / nmed; ++ ++ // cout << "hello2" << endl; ++ ++ DLong *hh = new DLong[ nEl]; ++ DLong* h1 = new DLong[ nEl/2]; ++ DLong* h2 = new DLong[ (nEl+1)/2]; ++ ++ DLong accumStride = 1; ++ if (nmed > 1) ++ for( DLong i=0; iDim(i); ++ ++ BaseGDL *op1, *op2, *op3; ++ if (dbl) op3 = new DDoubleGDL(2); ++ else op3 = new DFloatGDL(2); ++ ++ // nEl_extern is used to store "nEl" initial value ++ DLong nanIx, nEl_extern; ++ nEl_extern=nEl; ++ // if (nmed > 1) nEl_extern = p0->N_Elements() / nmed; ++ //else nEl_extern = p0->N_Elements(); ++ ++ // cout << "hello type" << p0->Type() << endl; ++ ++ // Loop over all subarray medians ++ for (SizeT k=0; kType() == GDL_DOUBLE) { ++ DDoubleGDL* p0F = static_cast(p0); ++ for( DLong i=nEl-1; i >= 0; --i) { ++ if( isnan((*p0F)[i])) { ++ --nanIx; ++ hh[i] = hh[nanIx]; ++ hh[ nanIx] = i; ++ } ++ } ++ } ++ ++ if (p0->Type() == GDL_FLOAT) { ++ DFloatGDL* p0F = static_cast(p0); ++ for( DLong i=nEl-1; i >= 0; --i) { ++ if( isnan((*p0F)[i])) { ++ --nanIx; ++ hh[i] = hh[nanIx]; ++ hh[ nanIx] = i; ++ } ++ } ++ } ++ ++ //cout << "nEl " << nEl << " nanIx " << nanIx << endl; ++ nEl = nanIx; ++ } ++ else ++ { ++ nanIx = nEl; ++ nEl=nEl_extern; ++ ++ // DLong nanIx = nEl; ++ // Starting Element ++ DLong start = accumStride * p0->Dim(dim-1) * (k / accumStride) + ++ (k % accumStride); ++ for( DLong i=0; iType() == GDL_FLOAT) { ++ DFloatGDL* p0F = static_cast(p0); ++ for( DLong i=nEl-1; i >= 0; --i) { ++ jj=start + i * accumStride; ++ if( isnan((*p0F)[ jj]) ) { ++ --nanIx; ++ hh[i] = hh[nanIx]; ++ hh[ nanIx] = i; ++ } ++ } ++ nEl = nanIx; ++ } ++ ++ if (p0->Type() == GDL_DOUBLE) { ++ DDoubleGDL* p0F = static_cast(p0); ++ for( DLong i=nEl-1; i >= 0; --i) { ++ jj=start + i * accumStride; ++ if( isnan((*p0F)[ jj]) ) { ++ --nanIx; ++ hh[i] = hh[nanIx]; ++ hh[ nanIx] = i; ++ } ++ } ++ //cout << "nanIx :" << nanIx << "nEl :" << nEl << endl; ++ nEl = nanIx; ++ } ++ } ++ DLong medEl, medEl_1; ++ ++ // call the sort routine ++ if (nEl > 1) { ++ MergeSortOpt( p0, hh, h1, h2, nEl); ++ medEl = hh[ nEl/2]; ++ medEl_1 = hh[ nEl/2 - 1]; ++ } else { ++ if (nEl == 1) { ++ medEl = hh[0]; ++ medEl_1 = hh[0]; ++ } else ++ { // normal case, more than one element, nothing to do ++ //cout << "gasp : no result ! " << endl; ++ } ++ } ++ ++ if (nEl <= 0) { // we have a NaN ++ if (dbl) (*static_cast(res))[k] = d_nan; ++ else (*static_cast(res))[k] = f_nan; ++ } else { ++ //cout << k << "" << (*static_cast(p0))[medEl] << " " ++ // << (*static_cast(p0))[medEl_1] << endl; ++ //cout << "k :" << k << endl; ++ if( (nEl % 2) == 1 || !e->KeywordSet( evenIx)) { ++ if (nmed == 1) ++ res = p0->NewIx(medEl)->Convert2(type, BaseGDL::CONVERT); ++ else { ++ if (noconv) ++ { ++ if (dbl) (*static_cast(res))[k] = (*static_cast(p0))[medEl]; ++ else (*static_cast(res))[k] = (*static_cast(p0))[medEl]; ++ } ++ else ++ { ++ op1 = p0->NewIx(medEl)->Convert2(type, BaseGDL::CONVERT); ++ if (dbl) (*static_cast(res))[k] = (*static_cast(op1))[0]; ++ else (*static_cast(res))[k] = (*static_cast(op1))[0]; ++ delete(op1); ++ } ++ } ++ } else { ++ if (noconv) ++ { ++ if (dbl) (*static_cast(res))[k] = .5 * ( ++ (*static_cast(p0))[medEl] + ++ (*static_cast(p0))[medEl_1] ++ ); ++ else (*static_cast(res))[k] = .5 * ( ++ (*static_cast(p0))[medEl] + ++ (*static_cast(p0))[medEl_1] ++ ); ++ } ++ else ++ { ++ op1 = p0->NewIx(medEl)->Convert2(type, BaseGDL::CONVERT); ++ op2 = p0->NewIx(medEl_1)->Convert2(type, BaseGDL::CONVERT); ++ if (nmed == 1) res = op2->Add(op1)->Div(op3); // TODO: leak with res? ++ else ++ { ++ if (dbl) (*static_cast(res))[k] = ++ (*static_cast((op2->Add(op1)->Div(op3))))[0]; ++ else (*static_cast(res))[k] = ++ (*static_cast((op2->Add(op1)->Div(op3))))[0]; ++ delete(op2); ++ } ++ delete(op1); ++ } ++ } ++ } ++ } ++ delete(op3); ++ delete[] h1; ++ delete[] h2; ++ delete[] hh; ++ ++ return res; ++ } ++ ++ // begin of the part 2: with "width" param ++ if( nParam == 2) { ++ // with parameter Width : median filtering with no optimisation, ++ // such as histogram algorithms. ++ // Copyright: (C) 2008 by Nicolas Galmiche ++ ++ // basic checks on "vector/array" input ++ DDoubleGDL* p0 = e->GetParAs( 0); ++ ++ if( p0->Rank() > 2) ++ e->Throw( "Only 1 or 2 dimensions allowed: "+ e->GetParString(0)); ++ ++ // basic checks on "width" input ++ DDoubleGDL* p1d = e->GetParAs(1); ++ ++ if (p1d->N_Elements() > 1 || (*p1d)[0] <=0 ) ++ e->Throw( "Width must be a positive scalar or 1 (positive) element array in this context: "+ e->GetParString(0)); ++ DLong MaxAllowedWidth=0; ++ if (p0->Rank() == 1) MaxAllowedWidth=p0->N_Elements(); ++ if (p0->Rank() == 2) { ++ MaxAllowedWidth=p0->Dim(0); ++ if (p0->Dim(1) < MaxAllowedWidth) MaxAllowedWidth=p0->Dim(1); ++ } ++ const int debug =0; ++ if (debug == 1) { ++ cout << "X dim " << p0->Dim(0) <Dim(1) <Throw("Width must be > 1, and < dimension of array (NaN or Inf)"); ++ ++ DLongGDL* p1 = e->GetParAs(1); ++ ++ DDoubleGDL *tamp = new DDoubleGDL(p0->Dim(),BaseGDL::NOZERO); ++ DDouble min=((*p0)[0]); ++ DDouble max=min; ++ ++ for (SizeT ii=0 ; iiN_Elements() ; ++ii) ++ {(*tamp)[ii]=(*p0)[ii]; ++ if ( (*p0)[ii] < min ) min = ((*p0)[ii]); ++ if ( (*p0)[ii] > max ) max = ((*p0)[ii]); ++ } ++ ++ //---------------------------- END d'acquisistion des paramètres ------------------------------------- ++ ++ ++ static int evenIx = e->KeywordIx( "EVEN"); ++ static int doubleIx = e->KeywordIx( "DOUBLE"); ++ static DStructGDL *Values = SysVar::Values(); ++ DDouble d_nan=(*static_cast(Values->GetTag(Values->Desc()->TagIndex("D_NAN"), 0)))[0]; ++ DDouble d_infinity= (*static_cast(Values->GetTag(Values->Desc()->TagIndex("D_INFINITY"), 0)))[0]; ++ ++ //------------------------------ Init variables and allocation --------------------------------------- ++ SizeT width=(*p1)[0]; ++ SizeT N_MaskElem= width*width; ++ SizeT larg = p0->Stride(1); ++ SizeT haut = p0->Stride(2)/larg; ++ SizeT lim= static_cast(round(width/2)); ++ SizeT init=(lim*larg+lim); ++ ++ // we don't go further if dimension(s) versus not width OK ++ ++ if (debug == 1) {cout << "ici" <Rank() == 1) { ++ if (larg < width || width==1 ) e->Throw( "Width must be > 1, and < width of vector"); ++ } ++ if ( p0->Rank() == 2) { ++ if (larg < width || haut < width || width==1) e->Throw("Width must be > 1, and < dimension of array"); ++ } ++ ++ // for 2D arrays, we use the algorithm described in paper ++ // from T. Huang, G. Yang, and G. Tang, “A Fast Two-Dimensional Median ++ // Filtering Algorithm,” IEEE Trans. Acoust., Speech, Signal Processing, ++ // vol. 27, no. 1, pp. 13–18, 1979. ++ ++ if ( (e->GetParDefined( 0)->Type() == GDL_BYTE || ++ e->GetParDefined( 0)->Type() == GDL_INT || ++ e->GetParDefined( 0)->Type() == GDL_UINT || ++ e->GetParDefined( 0)->Type() == GDL_LONG || ++ e->GetParDefined( 0)->Type() == GDL_ULONG || ++ e->GetParDefined( 0)->Type() == GDL_LONG64 || ++ e->GetParDefined( 0)->Type() == GDL_ULONG64) && ++ (haut>1)) ++ { ++ SizeT taille=static_cast(abs(max)-min+1); ++ DDoubleGDL* Histo = new DDoubleGDL(taille,BaseGDL::NOZERO); ++ if (width % 2 ==0) ++ { ++ for(SizeT i=0 ; i((*p0)[ii+yy*larg]-min)]++; ++ } ++ ++ while (ltmed+(*Histo)[med]<=(N_MaskElem /2)) ++ { ++ ltmed+= static_cast((*Histo)[med]); ++ ++med; ++ } ++ if (e->KeywordSet( evenIx)) ++ { ++ ++ SizeT EvenMed=med; ++ //if ((*Histo)[EvenMed]==1 || (ltmed!=0 && ltmed !=(N_MaskElem /2) -1)) ++ if ((*Histo)[EvenMed]==1 || (ltmed!=0 && N_MaskElem /2- ltmed!=1) ) ++ { ++ while ((*Histo)[EvenMed-1]==0) ++ { EvenMed--;} ++ (*tamp)[init+i*larg]=((med+min)+(EvenMed-1+min))/2; ++ } ++ else ++ (*tamp)[init+i*larg]=med+min; ++ } ++ else ++ {(*tamp)[init+i*larg]=med+min; } ++ ++ for(SizeT j=init+i*larg +1; j((*p0)[initMask-1+k*larg]-min)]--; ++ if ((*p0)[initMask-1+k*larg]-min((*p0)[initMask+k*larg+2*lim-1]-min)]++; ++ if ((*p0)[initMask+k*larg+2*lim-1]-minN_MaskElem /2) ++ { ++ while(ltmed>N_MaskElem /2) ++ { ++ --med; ++ ltmed-=static_cast((*Histo)[med]); ++ } ++ } ++ else ++ { ++ while (ltmed+(*Histo)[med]<=(N_MaskElem /2)) ++ { ++ ltmed+= static_cast((*Histo)[med]); ++ ++med; ++ } ++ } ++ ++ if (e->KeywordSet( evenIx)) ++ { ++ SizeT EvenMed=med; ++ if ((*Histo)[EvenMed]==1 || (ltmed!=0 &&N_MaskElem /2- ltmed!=1 )) ++ { ++ while ((*Histo)[EvenMed-1]==0) ++ { EvenMed--;} ++ (*tamp)[j]=((med+min)+(EvenMed-1+min))/2; ++ } ++ else ++ {(*tamp)[j]=med+min; } ++ } ++ else ++ {(*tamp)[j]=med+min; } ++ } ++ } ++ } ++ else ++ { ++ for(SizeT i=0 ; i((*p0)[ii+yy*larg]-min)]++; ++ } ++ ++ while (ltmed+(*Histo)[med]<=(N_MaskElem /2)) ++ { ++ ltmed+= static_cast((*Histo)[med]); ++ ++med; ++ } ++ (*tamp)[init+i*larg]=med+min; ++ ++ for(SizeT j=init+i*larg +1; j((*p0)[initMask-1+k*larg]-min)]--; ++ if ((*p0)[initMask-1+k*larg]-min((*p0)[initMask+k*larg+2*lim]-min)]++; ++ if ((*p0)[initMask+k*larg+2*lim]-minN_MaskElem /2) ++ { ++ while(ltmed>N_MaskElem /2) ++ { ++ --med; ++ ltmed-=static_cast((*Histo)[med]); ++ } ++ } ++ else ++ { ++ while (ltmed+(*Histo)[med]<=(N_MaskElem /2)) ++ { ++ ltmed+= static_cast((*Histo)[med]); ++ ++med; ++ } ++ } ++ ++ (*tamp)[j]=med+min; ++ ++ } ++ } ++ } ++ ++ } ++ else ++ { ++ DLong* hh; ++ DLong* h1; ++ DLong* h2; ++ DDoubleGDL* Mask,*Mask1D; ++ if ( p0->Rank() != 1 ) ++ { ++ hh = new DLong[ N_MaskElem]; ++ h1 = new DLong[ N_MaskElem/2]; ++ h2= new DLong[ (N_MaskElem+1)/2]; ++ Mask = new DDoubleGDL(N_MaskElem,BaseGDL::NOZERO); ++ ++ for( DLong i=0; iRank() == 1 )//------------------------ For a vector with even width ------------------- ++ { ++ for (SizeT col= lim ; col(Mask1Dbis); ++ MergeSortOpt( besort, hhbis, h1bis, h2bis,(width - ctl_NaN)); ++ if (e->KeywordSet( evenIx)&& (width - ctl_NaN) % 2 == 0) ++ (*tamp)[col]=((*Mask1Dbis)[hhbis[ (width-ctl_NaN)/2]]+(*Mask1Dbis ++ )[hhbis [ (width - ctl_NaN-1)/2]])/2; ++ else ++ (*tamp)[col]=(*Mask1Dbis)[hhbis[ (width- ctl_NaN)/2]]; ++ delete[]hhbis; ++ delete[]h2bis; ++ delete[]h1bis; ++ } ++ } ++ else ++ { ++ BaseGDL* besort=static_cast(Mask1D); ++ MergeSortOpt( besort, hh, h1, h2,width ); // call the sort routine ++ ++ if (e->KeywordSet( evenIx)) ++ ++ (*tamp)[col]=((*Mask1D)[hh[ width/2]]+(*Mask1D)[hh[ (width-1)/2]])/2; ++ else ++ (*tamp)[col]=(*Mask1D)[hh[ width/2]];// replace value by Mask median ++ } ++ } ++ ++ } ++ else//------------------------ For an array with even width ------------------- ++ { ++ SizeT jj; ++ for(SizeT i=0 ; i(Maskb); ++ MergeSortOpt( besort, hhb, h1b, h2b,(N_MaskElem - ctl_NaN)); ++ if ((N_MaskElem - ctl_NaN) % 2 == 0 && e->KeywordSet( evenIx)) ++ (*tamp)[j]=((*Maskb)[hhb[ (N_MaskElem-ctl_NaN)/2]]+(*Maskb)[hhb ++ [ (N_MaskElem - ++ ctl_NaN-1)/2]])/2; ++ else ++ (*tamp)[j]=(*Maskb)[hhb[ (N_MaskElem- ctl_NaN)/2]]; ++ delete[]hhb; ++ delete[]h2b; ++ delete[]h1b; ++ } ++ } ++ else ++ { ++ BaseGDL* besort=static_cast(Mask); ++ MergeSortOpt( besort, hh, h1, h2, N_MaskElem); // call the sort routine ++ if (e->KeywordSet( evenIx)) ++ (*tamp)[j]=((*Mask)[hh[ N_MaskElem/2]]+(*Mask)[hh[ (N_MaskElem-1)/2]])/2; ++ else ++ (*tamp)[j]=(*Mask)[hh[ N_MaskElem/2]];// replace value by median Mask one ++ } ++ } ++ } ++ } ++ } ++ ++ else ++ { ++ if ( p0->Rank() == 1 )//------------------------ For a vector with odd width ------------------- ++ ++ { ++ for (SizeT col= lim ; col(Mask1Dbis); ++ MergeSortOpt( besort, hhbis, h1bis, h2bis,(width - ctl_NaN)); ++ if (e->KeywordSet( evenIx)&& (width - ctl_NaN) % 2 == 0) ++ (*tamp)[col]=((*Mask1Dbis)[hhbis[ (width-ctl_NaN)/2]]+(*Mask1Dbis ++ )[hhbis [ (width - ctl_NaN-1)/2]])/2; ++ else(*tamp)[col]=(*Mask1Dbis)[hhbis[ (width- ctl_NaN)/2]]; ++ delete[]hhbis; ++ delete[]h2bis; ++ delete[]h1bis; ++ } ++ } ++ else ++ { ++ BaseGDL* besort=static_cast(Mask1D); ++ MergeSortOpt( besort, hh, h1, h2,width ); // call the sort routine ++ (*tamp)[col]=(*Mask1D)[hh[ (width)/2]]; // replace value by Mask median ++ } ++ } ++ ++ } ++ ++ else //----------------------------- For an array with odd width --------------------------------- ++ { ++ SizeT jj; ++ for(SizeT i=0 ; i(Maskb); ++ MergeSortOpt( besort, hhb, h1b, h2b,(N_MaskElem - ctl_NaN)); ++ if ((N_MaskElem - ctl_NaN) % 2 == 0 && e->KeywordSet( evenIx)) ++ (*tamp)[j]=((*Maskb)[hhb[ (N_MaskElem-ctl_NaN)/2]]+(*Maskb)[hhb ++ [ (N_MaskElem - ++ ctl_NaN-1)/2]])/2; ++ else(*tamp)[j]=(*Maskb)[hhb[(N_MaskElem- ctl_NaN)/2]]; ++ delete[]hhb; ++ delete[]h2b; ++ delete[]h1b; ++ } ++ } ++ else ++ { ++ BaseGDL* besort=static_cast(Mask); ++ MergeSortOpt( besort, hh, h1, h2, N_MaskElem); // call the sort routine ++ (*tamp)[j]=(*Mask)[hh[ (N_MaskElem)/2]]; // replace value by Mask median ++ } ++ } ++ } ++ } ++ } ++ ++ //--------------------------- END OF MEDIAN FILTER ALOGORITHMS ----------------------------------- ++ ++ delete[] h1; ++ delete[] h2; ++ delete[] hh; ++ } ++ if ( e->GetParDefined( 0)->Type() == GDL_DOUBLE || p0->Type() == GDL_COMPLEXDBL ||e->KeywordSet( doubleIx) ) ++ return tamp; ++ else if (e->GetParDefined( 0)->Type() == GDL_BYTE) ++ return tamp->Convert2(GDL_BYTE,BaseGDL::CONVERT); ++ ++ return tamp->Convert2(GDL_FLOAT,BaseGDL::CONVERT); ++ ++ }// end if ++ ++ }// end of median ++ ++ BaseGDL* shift_fun( EnvT* e) ++ { ++ SizeT nParam = e->NParam( 2); ++ ++ BaseGDL* p0 = e->GetParDefined( 0); ++ ++ SizeT nShift = nParam - 1; ++ if( nShift == 1) ++ { ++ DLong s1; ++ e->AssureLongScalarPar( 1, s1); ++ ++ // IncRef[Obj] done for GDL_PTR and GDL_OBJ ++ return p0->CShift( s1); ++ } ++ ++ if( p0->Rank() != nShift) ++ e->Throw( "Incorrect number of arguments."); ++ ++ DLong sIx[ MAXRANK]; ++ for( SizeT i=0; i< nShift; i++) ++ e->AssureLongScalarPar( i+1, sIx[ i]); ++ ++ if( p0->Type() == GDL_OBJ) ++ GDLInterpreter::IncRefObj( static_cast(p0)); ++ else if( p0->Type() == GDL_PTR) ++ GDLInterpreter::IncRef( static_cast(p0)); ++ ++ return p0->CShift( sIx); ++ } ++ ++ BaseGDL* arg_present( EnvT* e) ++ { ++ e->NParam( 1); ++ ++ if( !e->GlobalPar( 0)) ++ return new DIntGDL( 0); ++ ++ EnvBaseT* caller = e->Caller(); ++ if( caller == NULL) ++ return new DIntGDL( 0); ++ ++ BaseGDL** pp0 = &e->GetPar( 0); ++ ++ int ix = caller->FindGlobalKW( pp0); ++ if( ix == -1) ++ return new DIntGDL( 0); ++ ++ return new DIntGDL( 1); ++ } ++ ++ BaseGDL* eof_fun( EnvT* e) ++ { ++ e->NParam( 1); ++ ++ DLong lun; ++ e->AssureLongScalarPar( 0, lun); ++ ++ bool stdLun = check_lun( e, lun); ++ if( stdLun) ++ return new DIntGDL( 0); ++ ++ // nicer error message (Disregard if socket) ++ if ( fileUnits[ lun-1].SockNum() == -1) { ++ if( !fileUnits[ lun-1].IsOpen()) ++ throw GDLIOException( e->CallingNode(), "File unit is not open: "+i2s( lun)+"."); ++ ++ if( fileUnits[ lun-1].Eof()) ++ return new DIntGDL( 1); ++ } else { ++ // Socket ++ string *recvBuf = &fileUnits[ lun-1].RecvBuf(); ++ if (recvBuf->size() == 0) ++ return new DIntGDL( 1); ++ } ++ return new DIntGDL( 0); ++ } ++ ++ BaseGDL* convol( EnvT* e) ++ { ++ SizeT nParam=e->NParam( 2); ++ ++ BaseGDL* p0 = e->GetNumericParDefined( 0); ++ if( p0->Rank() == 0) ++ e->Throw( "Expression must be an array in this context: "+ ++ e->GetParString(0)); ++ ++ BaseGDL* p1 = e->GetNumericParDefined( 1); ++ if( p1->Rank() == 0) ++ e->Throw( "Expression must be an array in this context: "+ ++ e->GetParString(1)); ++ ++ if( p0->N_Elements() <= p1->N_Elements()) ++ e->Throw( "Incompatible dimensions for Array and Kernel."); ++ ++ // rank 1 for kernel works always ++ if( p1->Rank() != 1) ++ { ++ SizeT rank = p0->Rank(); ++ if( rank != p1->Rank()) ++ e->Throw( "Incompatible dimensions for Array and Kernel."); ++ ++ for( SizeT r=0; rDim( r) <= p1->Dim( r)) ++ e->Throw( "Incompatible dimensions for Array and Kernel."); ++ } ++ ++ // convert kernel to array type ++ auto_ptr p1Guard; ++ if( p0->Type() == GDL_BYTE) ++ { ++ if( p1->Type() != GDL_INT) ++ { ++ p1 = p1->Convert2( GDL_INT, BaseGDL::COPY); ++ p1Guard.reset( p1); ++ } ++ } ++ else if( p0->Type() != p1->Type()) ++ { ++ p1 = p1->Convert2( p0->Type(), BaseGDL::COPY); ++ p1Guard.reset( p1); ++ } ++ ++ BaseGDL* scale; ++ auto_ptr scaleGuard; ++ if( nParam > 2) ++ { ++ scale = e->GetParDefined( 2); ++ if( scale->Rank() > 0) ++ e->Throw( "Expression must be a scalar in this context: "+ ++ e->GetParString(2)); ++ ++ // p1 here handles GDL_BYTE case also ++ if( p1->Type() != scale->Type()) ++ { ++ scale = scale->Convert2( p1->Type(),BaseGDL::COPY); ++ scaleGuard.reset( scale); ++ } ++ } ++ else ++ { ++ scale = p1->New( dimension(), BaseGDL::ZERO); ++ } ++ ++ bool center = true; ++ static int centerIx = e->KeywordIx( "CENTER"); ++ if( e->KeywordPresent( centerIx)) ++ { ++ DLong c; ++ e->AssureLongScalarKW( centerIx, c); ++ center = (c != 0); ++ } ++ ++ // overrides EDGE_TRUNCATE ++ static int edge_wrapIx = e->KeywordIx( "EDGE_WRAP"); ++ bool edge_wrap = e->KeywordSet( edge_wrapIx); ++ static int edge_truncateIx = e->KeywordIx( "EDGE_TRUNCATE"); ++ bool edge_truncate = e->KeywordSet( edge_truncateIx); ++ ++ int edgeMode = 0; ++ if( edge_wrap) ++ edgeMode = 1; ++ else if( edge_truncate) ++ edgeMode = 2; ++ ++ // p0, p1 and scale have same type ++ // p1 has rank of 1 or same rank as p0 with each dimension smaller than p0 ++ // scale is a scalar ++ return p0->Convol( p1, scale, center, edgeMode); ++ } ++ ++ BaseGDL* rebin_fun( EnvT* e) ++ { ++ SizeT nParam = e->NParam( 2); ++ ++ BaseGDL* p0 = e->GetNumericParDefined( 0); ++ ++ SizeT rank = p0->Rank(); ++ ++ if( rank == 0) ++ e->Throw( "Expression must be an array in this context: "+ ++ e->GetParString(0)); ++ ++ SizeT resDimInit[ MAXRANK]; ++ ++ DLongGDL* p1 = e->GetParAs(1); ++ if (p1->Rank() > 0 && nParam > 2) ++ e->Throw("The new dimensions must either be specified as an array or as a set of scalars."); ++ SizeT np = p1->Rank() == 0 ? nParam : p1->N_Elements() + 1; ++ ++ for( SizeT p=1; pRank() == 0) e->AssureLongScalarPar( p, newDim); ++ else newDim = (*p1)[p - 1]; ++ ++ if( newDim <= 0) ++ e->Throw( "Array dimensions must be greater than 0."); ++ ++ if( rank >= p) ++ { ++ SizeT oldDim = p0->Dim( p-1); ++ ++ if( newDim > oldDim) ++ { ++ if( (newDim % oldDim) != 0) ++ e->Throw( "Result dimensions must be integer factor " ++ "of original dimensions."); ++ } ++ else ++ { ++ if( (oldDim % newDim) != 0) ++ e->Throw( "Result dimensions must be integer factor " ++ "of original dimensions."); ++ } ++ } ++ ++ resDimInit[ p-1] = newDim; ++ } ++ ++ dimension resDim( resDimInit, np-1); ++ ++ static int sampleIx = e->KeywordIx( "SAMPLE"); ++ bool sample = e->KeywordSet( sampleIx); ++ ++ return p0->Rebin( resDim, sample); ++ } ++ ++ BaseGDL* obj_class( EnvT* e) ++ { ++ SizeT nParam = e->NParam(); ++ ++ static int countIx = e->KeywordIx( "COUNT"); ++ static int superIx = e->KeywordIx( "SUPERCLASS"); ++ ++ bool super = e->KeywordSet( superIx); ++ ++ bool count = e->KeywordPresent( countIx); ++ if( count) ++ e->AssureGlobalKW( countIx); ++ ++ if( nParam > 0) ++ { ++ BaseGDL* p0 = e->GetParDefined( 0); ++ ++ if( p0->Type() != GDL_STRING && p0->Type() != GDL_OBJ) ++ e->Throw( "Argument must be a scalar object reference or string: "+ ++ e->GetParString(0)); ++ ++ if( !p0->Scalar()) ++ e->Throw( "Expression must be a scalar or 1 element " ++ "array in this context: "+e->GetParString(0)); ++ ++ DStructDesc* objDesc; ++ ++ if( p0->Type() == GDL_STRING) ++ { ++ DString objName; ++ e->AssureScalarPar( 0, objName); ++ objName = StrUpCase( objName); ++ ++ objDesc = FindInStructList( structList, objName); ++ if( objDesc == NULL) ++ { ++ if( count) ++ e->SetKW( countIx, new DLongGDL( 0)); ++ return new DStringGDL( ""); ++ } ++ } ++ else // GDL_OBJ ++ { ++ DObj objRef; ++ e->AssureScalarPar( 0, objRef); ++ ++ if( objRef == 0) ++ { ++ if( count) ++ e->SetKW( countIx, new DLongGDL( 0)); ++ return new DStringGDL( ""); ++ } ++ ++ DStructGDL* oStruct; ++ try { ++ oStruct = e->GetObjHeap( objRef); ++ } ++ catch ( GDLInterpreter::HeapException) ++ { // non valid object ++ if( count) ++ e->SetKW( countIx, new DLongGDL( 0)); ++ return new DStringGDL( ""); ++ } ++ ++ objDesc = oStruct->Desc(); // cannot be NULL ++ } ++ ++ if( !super) ++ { ++ if( count) ++ e->SetKW( countIx, new DLongGDL( 1)); ++ return new DStringGDL( objDesc->Name()); ++ } ++ ++ deque< string> pNames; ++ objDesc->GetParentNames( pNames); ++ ++ SizeT nNames = pNames.size(); ++ ++ if( count) ++ e->SetKW( countIx, new DLongGDL( nNames)); ++ ++ if( nNames == 0) ++ { ++ return new DStringGDL( ""); ++ } ++ ++ DStringGDL* res = new DStringGDL( dimension( nNames), ++ BaseGDL::NOZERO); ++ ++ for( SizeT i=0; iThrow( "Conflicting keywords."); ++ ++ SizeT nObj = structList.size(); ++ ++ DStringGDL* res = new DStringGDL( dimension( nObj), ++ BaseGDL::NOZERO); ++ ++ for( SizeT i=0; iName(); ++ } ++ ++ return res; ++ } ++ ++ BaseGDL* obj_isa( EnvT* e) ++ { ++ SizeT nParam = e->NParam( 2); ++ ++ BaseGDL* p0 = e->GetPar( 0); ++ if( p0 == NULL || p0->Type() != GDL_OBJ) ++ e->Throw( "Object reference type required in this context: "+ ++ e->GetParString(0)); ++ ++ DString className; ++ e->AssureScalarPar( 1, className); ++ className = StrUpCase( className); ++ ++ DObjGDL* pObj = static_cast( p0); ++ ++ DByteGDL* res = new DByteGDL( pObj->Dim()); // zero ++ ++ GDLInterpreter* interpreter = e->Interpreter(); ++ ++ SizeT nElem = pObj->N_Elements(); ++ for( SizeT i=0; iObjValid( (*pObj)[ i])) ++ { ++ DStructGDL* oStruct = e->GetObjHeap( (*pObj)[i]); ++ if( oStruct->Desc()->IsParent( className)) ++ (*res)[i] = 1; ++ } ++ } ++ ++ return res; ++ } ++ ++ BaseGDL* n_tags( EnvT* e) ++ { ++ e->NParam( 1); ++ ++ BaseGDL* p0 = e->GetPar( 0); ++ if( p0 == NULL) ++ return new DLongGDL( 0); ++ ++ if( p0->Type() != GDL_STRUCT) ++ return new DLongGDL( 0); ++ ++ DStructGDL* s = static_cast( p0); ++ ++ //static int lengthIx = e->KeywordIx( "DATA_LENGTH"); ++ //bool length = e->KeywordSet( lengthIx); ++ ++ // we don't know now how to distinghuis the 2 following cases ++ if(e->KeywordSet("DATA_LENGTH")) ++ return new DLongGDL( s->Sizeof()); ++ ++ if(e->KeywordSet("LENGTH")) ++ return new DLongGDL( s->Sizeof()); ++ ++ return new DLongGDL( s->Desc()->NTags()); ++ } ++ ++ BaseGDL* bytscl( EnvT* e) ++ { ++ SizeT nParam = e->NParam( 1); ++ ++ BaseGDL* p0=e->GetNumericParDefined( 0); ++ ++ static int minIx = e->KeywordIx( "MIN"); ++ static int maxIx = e->KeywordIx( "MAX"); ++ static int topIx = e->KeywordIx( "TOP"); ++ bool omitNaN = e->KeywordPresent( 3); ++ ++ DLong topL=255; ++ if( e->GetKW( topIx) != NULL) ++ e->AssureLongScalarKW( topIx, topL); ++ if (topL > 255) topL=255; // Bug corrected! ++ DByte top = static_cast(topL); ++ DDouble dTop = static_cast(top); ++ ++ DDouble min; ++ bool minSet = false; ++ // SA: handling 3 parameters to emulate undocumented IDL behaviour ++ // of translating second and third arguments to MIN and MAX, respectively ++ // (parameters have precedence over keywords) ++ if (nParam >= 2) ++ { ++ e->AssureDoubleScalarPar(1, min); ++ minSet = true; ++ } ++ else if (e->GetKW(minIx) != NULL) ++ { ++ e->AssureDoubleScalarKW(minIx, min); ++ minSet = true; ++ } ++ ++ DDouble max; ++ bool maxSet = false; ++ if (nParam == 3) ++ { ++ e->AssureDoubleScalarPar(2, max); ++ maxSet = true; ++ } ++ else if (e->GetKW(maxIx) != NULL) ++ { ++ e->AssureDoubleScalarKW(maxIx, max); ++ maxSet = true; ++ } ++ ++ DDoubleGDL* dRes = ++ static_cast(p0->Convert2( GDL_DOUBLE, BaseGDL::COPY)); ++ ++ DLong maxEl, minEl; ++ if( !maxSet || !minSet) ++ dRes->MinMax( &minEl, &maxEl, NULL, NULL, omitNaN); ++ if( !minSet) ++ min = (*dRes)[ minEl]; ++ if( !maxSet) ++ max = (*dRes)[ maxEl]; ++ ++ SizeT nEl = dRes->N_Elements(); ++ for( SizeT i=0; i= max) (*dRes)[ i] = dTop; ++ else ++ { ++ // SA: floor is used for integer types to simulate manipulation on input data types ++ if (IntType(p0->Type())) (*dRes)[ i] = floor(((dTop + 1.)*(d - min) - 1.) / (max-min)); ++ // SA (?): here floor is used (instead of round) to simulate IDL behaviour ++ else (*dRes)[ i] = floor((d - min) / (max-min) * (dTop + .9999)); ++ } ++ } ++ ++ return dRes->Convert2( GDL_BYTE); ++ } ++ ++ BaseGDL* strtok_fun( EnvT* e) ++ { ++ SizeT nParam=e->NParam( 1); ++ ++ DString stringIn; ++ e->AssureStringScalarPar( 0, stringIn); ++ ++ DString pattern = " \t"; ++ if(nParam > 1) { ++ e->AssureStringScalarPar( 1, pattern); ++ } ++ ++ static int extractIx = e->KeywordIx( "EXTRACT"); ++ bool extract = e->KeywordSet( extractIx); ++ ++ static int lengthIx = e->KeywordIx( "LENGTH"); ++ bool lengthPresent = e->KeywordPresent( lengthIx); ++ ++ if( extract && lengthPresent) ++ e->Throw( "Conflicting keywords."); ++ ++ static int pre0Ix = e->KeywordIx( "PRESERVE_NULL"); ++ bool pre0 = e->KeywordSet( pre0Ix); ++ ++ static int regexIx = e->KeywordIx( "REGEX"); ++ bool regex = e->KeywordPresent( regexIx); ++ char err_msg[MAX_REGEXPERR_LENGTH]; ++ regex_t regexp; ++ ++ deque tokenStart; ++ deque tokenLen; ++ ++ int strLen = stringIn.length(); ++ ++ DString escape = ""; ++ e->AssureStringScalarKWIfPresent( "ESCAPE", escape); ++ deque escList; ++ long pos = 0; ++ while(pos != string::npos) ++ { ++ pos = stringIn.find_first_of( escape, pos); ++ if( pos != string::npos) ++ { ++ escList.push_back( pos+1); // remember escaped char ++ pos += 2; // skip escaped char ++ } ++ } ++ deque::iterator escBeg = escList.begin(); ++ deque::iterator escEnd = escList.end(); ++ ++ long tokB = 0; ++ long tokE; ++ long nextE = 0; ++ long actLen; ++ ++ // If regex then compile regex ++ if( regex) { ++ if (pattern == " \t") pattern = " "; // regcomp doesn't like "\t" JMG ++ int compRes = regcomp( ®exp, pattern.c_str(), REG_EXTENDED); ++ if (compRes) { ++ regerror(compRes, ®exp, err_msg, MAX_REGEXPERR_LENGTH); ++ e->Throw( "Error processing regular expression: "+ ++ pattern+"\n "+string(err_msg)+"."); ++ } ++ } ++ ++ for(;;) ++ { ++ regmatch_t pmatch[1]; ++ if( regex) { ++ int matchres = regexec( ®exp, stringIn.c_str()+nextE, 1, pmatch, 0); ++ tokE = matchres? -1:pmatch[0].rm_so; ++ } else { ++ tokE = stringIn.find_first_of( pattern, nextE); ++ } ++ ++ if( tokE == string::npos) ++ { ++ actLen = strLen - tokB; ++ if( actLen > 0 || pre0) ++ { ++ tokenStart.push_back( tokB); ++ tokenLen.push_back( actLen); ++ } ++ break; ++ } ++ ++ if( find( escBeg, escEnd, tokE) == escEnd) ++ { ++ if (regex) actLen = tokE; else actLen = tokE - tokB; ++ if( actLen > 0 || pre0) ++ { ++ tokenStart.push_back( tokB); ++ tokenLen.push_back( actLen); ++ } ++ if (regex) tokB += pmatch[0].rm_eo; else tokB = tokE + 1; ++ } ++ if (regex) nextE += pmatch[0].rm_eo; else nextE = tokE + 1; ++ } // for(;;) ++ ++ if (regex) regfree( ®exp); ++ ++ SizeT nTok = tokenStart.size(); ++ ++ if( !extract) ++ { ++ if( lengthPresent) ++ { ++ e->AssureGlobalKW( lengthIx); ++ ++ if( nTok > 0) ++ { ++ dimension dim(nTok); ++ DLongGDL* len = new DLongGDL(dim); ++ for(int i=0; i < nTok; i++) ++ (*len)[i] = tokenLen[i]; ++ ++ e->SetKW( lengthIx, len); ++ } ++ else ++ { ++ e->SetKW( lengthIx, new DLongGDL( 0)); ++ } ++ } ++ ++ if( nTok == 0) return new DLongGDL( 0); ++ ++ dimension dim(nTok); ++ DLongGDL* d = new DLongGDL(dim); ++ for(int i=0; i < nTok; i++) ++ (*d)[i] = tokenStart[i]; ++ return d; ++ } ++ ++ // EXTRACT ++ if( nTok == 0) return new DStringGDL( ""); ++ ++ dimension dim(nTok); ++ DStringGDL *d = new DStringGDL(dim); ++ for(int i=0; i < nTok; i++) ++ { ++ (*d)[i] = stringIn.substr(tokenStart[i], tokenLen[i]); ++ ++ // remove escape ++ DString& act = (*d)[i]; ++ long escPos = act.find_first_of( escape, 0); ++ while( escPos != string::npos) ++ { ++ act = act.substr( 0, escPos)+act.substr( escPos+1); ++ escPos = act.find_first_of( escape, escPos+1); ++ } ++ } ++ return d; ++ } ++ ++ BaseGDL* getenv_fun( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ ++ static int environmentIx = e->KeywordIx( "ENVIRONMENT" ); ++ bool environment = e->KeywordSet( environmentIx ); ++ ++ SizeT nEnv; ++ DStringGDL* env; ++ ++ if( environment) { ++ ++ if(nParam != 0) ++ e->Throw( "Incorrect number of arguments."); ++ ++ // determine number of environment entries ++ for(nEnv = 0; environ[nEnv] != NULL ; ++nEnv); ++ ++ dimension dim( nEnv ); ++ env = new DStringGDL(dim); ++ ++ // copy stuff into local string array ++ for(SizeT i=0; i < nEnv ; ++i) ++ (*env)[i] = environ[i]; ++ ++ } else { ++ ++ if(nParam != 1) ++ e->Throw( "Incorrect number of arguments."); ++ ++ DStringGDL* name = e->GetParAs(0); ++ nEnv = name->N_Elements(); ++ ++ env = new DStringGDL( name->Dim()); ++ ++ // copy the stuff into local string only if param found ++ char *resPtr; ++ for(SizeT i=0; i < nEnv ; ++i) ++ { ++ // handle special environment variables ++ // GDL_TMPDIR, IDL_TMPDIR ++ if( (*name)[i] == "GDL_TMPDIR" || (*name)[i] == "IDL_TMPDIR") ++ { ++ resPtr = getenv((*name)[i].c_str()); ++ ++ if( resPtr != NULL) ++ (*env)[i] = resPtr; ++ else ++ (*env)[i] = SysVar::Dir(); ++ ++ AppendIfNeeded( (*env)[i], "/"); ++ } ++ else // normal environment variables ++ if( (resPtr = getenv((*name)[i].c_str())) ) ++ (*env)[i] = resPtr; ++ } ++ } ++ ++ return env; ++ } ++ ++ BaseGDL* tag_names_fun( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ DStructGDL* struc= e->GetParAs(0); ++ ++ static int structureNameIx = e->KeywordIx( "STRUCTURE_NAME" ); ++ bool structureName = e->KeywordSet( structureNameIx ); ++ ++ DStringGDL* tagNames; ++ ++ if(structureName){ ++ ++ if ((*struc).Desc()->Name() != "$truct") ++ tagNames = new DStringGDL((*struc).Desc()->Name()); ++ else ++ tagNames = new DStringGDL(""); ++ ++ } else { ++ SizeT nTags = (*struc).Desc()->NTags(); ++ ++ tagNames = new DStringGDL(dimension(nTags)); ++ for(int i=0; i < nTags; ++i) ++ (*tagNames)[i] = (*struc).Desc()->TagName(i); ++ } ++ ++ return tagNames; ++ } ++ ++// AC 12-Oc-2011: better version for: len=len, /Extract and /Sub ++// but it is still not perfect ++ ++ BaseGDL* stregex_fun( EnvT* e) ++ { ++ SizeT nParam=e->NParam( 2); ++ ++ DStringGDL* stringExpr= e->GetParAs(0); ++ dimension dim = stringExpr->Dim(); ++ ++ DString pattern; ++ e->AssureStringScalarPar(1, pattern); ++ if (pattern.size() <= 0) ++ { ++ e->Throw( "Error processing regular expression: "+pattern+ ++ "\n empty (sub)expression"); ++ } ++ ++ static int booleanIx = e->KeywordIx( "BOOLEAN" ); ++ bool booleanKW = e->KeywordSet( booleanIx ); ++ ++ static int extractIx = e->KeywordIx( "EXTRACT" ); ++ bool extractKW = e->KeywordSet( extractIx ); ++ ++ static int foldCaseIx = e->KeywordIx( "FOLD_CASE" ); ++ bool foldCaseKW = e->KeywordSet( foldCaseIx ); ++ ++ //XXXpch: this is wrong, should check arg_present ++ static int lengthIx = e->KeywordIx( "LENGTH" ); ++ bool lengthKW = e->KeywordPresent( lengthIx ); ++ ++ static int subexprIx = e->KeywordIx( "SUBEXPR" ); ++ bool subexprKW = e->KeywordSet( subexprIx ); ++ ++ if( booleanKW && (subexprKW || extractKW || lengthKW)) ++ e->Throw( "Conflicting keywords."); ++ ++ char err_msg[MAX_REGEXPERR_LENGTH]; ++ ++ // set the compile flags ++ int cflags = REG_EXTENDED; ++ if (foldCaseKW) ++ cflags |= REG_ICASE; ++ if (booleanKW) ++ cflags |= REG_NOSUB; ++ ++ // compile the regular expression ++ regex_t regexp; ++ int compRes = regcomp( ®exp, pattern.c_str(), cflags); ++ SizeT nSubExpr = regexp.re_nsub + 1; ++ ++ // cout << regexp.re_nsub << endl; ++ ++ if (compRes) { ++ regerror(compRes, ®exp, err_msg, MAX_REGEXPERR_LENGTH); ++ e->Throw( "Error processing regular expression: "+ ++ pattern+"\n "+string(err_msg)+"."); ++ } ++ ++ BaseGDL* result; ++ ++ if( booleanKW) ++ result = new DByteGDL(dim); ++ else if( extractKW && !subexprKW) ++ { ++ // cout << "my pb ! ? dim= " << dim << endl; ++ result = new DStringGDL(dim); ++ } ++ else if( subexprKW) ++ { ++ // cout << "my pb 2 ? dim= " << dim << endl; ++ dimension subExprDim = dim; ++ subExprDim >> nSubExpr; // m_schellens: commented in, needed ++ if( extractKW) ++ result = new DStringGDL(subExprDim); ++ else ++ result = new DLongGDL(subExprDim); ++ } ++ else ++ result = new DLongGDL(dim); ++ ++ DLongGDL* len = NULL; ++ if( lengthKW) { ++ e->AssureGlobalKW( lengthIx); ++ if( subexprKW) ++ { ++ dimension subExprDim = dim; ++ subExprDim >> nSubExpr; // m_schellens: commented in, needed ++ len = new DLongGDL(subExprDim); ++ } ++ else ++ { ++ len = new DLongGDL(dim); ++ } ++ for( SizeT i=0; iN_Elements(); ++i) ++ (*len)[i]= -1; ++ } ++ ++ int nmatch = 1; ++ if( subexprKW) nmatch = nSubExpr; ++ ++ regmatch_t* pmatch = new regmatch_t[nSubExpr]; ++ ArrayGuard pmatchGuard( pmatch); ++ ++ // cout << "dim " << dim.NDimElements() << endl; ++ for( SizeT s=0; s(result))[i+s*nSubExpr] = ++ (*stringExpr)[s].substr( pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so); ++// (*stringExpr)[i+s*nSubExpr].substr( pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so); ++ if( lengthKW) ++ (*len)[i+s*nSubExpr] = pmatch[i].rm_so != -1 ? pmatch[i].rm_eo - pmatch[i].rm_so : -1; ++// (*len)[i+s*nSubExpr] = pmatch[i].rm_eo - pmatch[i].rm_so; ++ } ++ } ++ else if ( subexprKW) ++ { ++ // cout << "je ne comprends pas v2: "<< nSubExpr << endl; ++ ++ // Loop through subexpressions & fill output array ++ for( SizeT i = 0; i(result))[i+s*nSubExpr] = pmatch[i].rm_so; ++ if( lengthKW) ++ (*len)[i+s*nSubExpr] = pmatch[i].rm_so != -1 ? pmatch[i].rm_eo - pmatch[i].rm_so : -1; ++ } ++ } ++ else ++ { ++ if( booleanKW) ++ (* static_cast(result))[s] = (matchres == 0); ++ else if ( extractKW) // !subExprKW ++ { ++ if( matchres == 0) ++ (* static_cast(result))[s] = ++ (*stringExpr)[s].substr( pmatch[0].rm_so, ++ pmatch[0].rm_eo - pmatch[0].rm_so); ++ } ++ else ++ (*static_cast(result))[s] = matchres ? -1 : pmatch[0].rm_so; ++ } ++ ++ if( lengthKW && !subexprKW) ++ (*len)[s] = pmatch[0].rm_eo - pmatch[0].rm_so; ++ } ++ ++ regfree( ®exp); ++ ++ if( lengthKW) ++ e->SetKW( lengthIx, len); ++ ++ return result; ++ } ++ ++ BaseGDL* routine_info( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ ++ static int functionsIx = e->KeywordIx( "FUNCTIONS" ); ++ bool functionsKW = e->KeywordSet( functionsIx ); ++ static int systemIx = e->KeywordIx( "SYSTEM" ); ++ bool systemKW = e->KeywordSet( systemIx ); ++ static int disabledIx = e->KeywordIx( "DISABLED" ); ++ bool disabledKW = e->KeywordSet( disabledIx ); ++ static int parametersIx = e->KeywordIx( "PARAMETERS" ); ++ bool parametersKW = e->KeywordSet( parametersIx ); ++ ++ if (parametersKW) ++ { ++ // sanity checks ++ if (systemKW || disabledKW) e->Throw("Conflicting keywords."); ++ if (nParam != 1) e->Throw("Incorrect number of arguments."); ++ ++ // getting the routine name from the first parameter ++ DString name; ++ e->AssureScalarPar(0, name); ++ name = StrUpCase(name); ++ ++ DSubUD* routine = functionsKW ++ ? static_cast(funList[GDLInterpreter::GetFunIx(name)]) ++ : static_cast(proList[GDLInterpreter::GetProIx(name)]); ++ SizeT np = routine->NPar(), nk = routine->NKey(); ++ ++ // creating the output anonymous structure ++ DStructDesc* stru_desc = new DStructDesc("$truct"); ++ SpDLong aLong; ++ stru_desc->AddTag("NUM_ARGS", &aLong); ++ stru_desc->AddTag("NUM_KW_ARGS", &aLong); ++ if (np > 0) ++ { ++ SpDString aStringArr(dimension((int)np)); ++ stru_desc->AddTag("ARGS", &aStringArr); ++ } ++ if (nk > 0) ++ { ++ SpDString aStringArr(dimension((int)nk)); ++ stru_desc->AddTag("KW_ARGS", &aStringArr); ++ } ++ DStructGDL* stru = new DStructGDL(stru_desc, dimension()); ++ ++ // filling the structure with information about the routine ++ stru->InitTag("NUM_ARGS", DLongGDL(np)); ++ stru->InitTag("NUM_KW_ARGS", DLongGDL(nk)); ++ if (np > 0) ++ { ++ DStringGDL *pnames = new DStringGDL(dimension(np)); ++ for (SizeT p = 0; p < np; ++p) (*pnames)[p] = routine->GetVarName(nk + p); ++ stru->InitTag("ARGS", *pnames); ++ GDLDelete(pnames); ++ } ++ if (nk > 0) ++ { ++ DStringGDL *knames = new DStringGDL(dimension(nk)); ++ for (SizeT k = 0; k < nk; ++k) (*knames)[k] = routine->GetKWName(k); ++ stru->InitTag("KW_ARGS", *knames); ++ GDLDelete(knames); ++ } ++ ++ // returning ++ return stru; ++ } ++ ++ // GDL does not have disabled routines ++ if( disabledKW) return new DStringGDL(""); ++ ++ // if( functionsKW || systemKW || nParam == 0) ++ // { ++ deque subList; ++ ++ if( functionsKW) ++ { ++ if( systemKW) ++ { ++ SizeT n = libFunList.size(); ++ if( n == 0) return new DStringGDL(""); ++ ++ DStringGDL* res = new DStringGDL( dimension( n), BaseGDL::NOZERO); ++ for( SizeT i = 0; iObjectName(); ++ ++ return res; ++ } ++ else ++ { ++ SizeT n = funList.size(); ++ if( n == 0) return new DStringGDL(""); ++ subList.resize( n); ++ ++ for( SizeT i = 0; iObjectName()); ++ } ++ } ++ else ++ { ++ if( systemKW) ++ { ++ SizeT n = libProList.size(); ++ if( n == 0) return new DStringGDL(""); ++ ++ DStringGDL* res = new DStringGDL( dimension( n), BaseGDL::NOZERO); ++ for( SizeT i = 0; iObjectName(); ++ ++ return res; ++ } ++ else ++ { ++ SizeT n = proList.size(); ++ if( n == 0) return new DStringGDL(""); ++ subList.resize( n); ++ ++ for( SizeT i = 0; iObjectName()); ++ } ++ } ++ ++ sort( subList.begin(), subList.end()); ++ SizeT nS = subList.size(); ++ ++ DStringGDL* res = new DStringGDL( dimension( nS), BaseGDL::NOZERO); ++ for( SizeT s=0; s ++ rl_prep_terminal (0); ++#endif ++ ++ SizeT nParam=e->NParam(); ++ ++ bool doWait = true; ++ if( nParam > 0) ++ { ++ doWait = false; ++ DLong waitArg = 0; ++ e->AssureLongScalarPar( 0, waitArg); ++ if( waitArg != 0) ++ { ++ doWait = true; ++ } ++ } ++ ++ // https://sourceforge.net/forum/forum.php?thread_id=3292183&forum_id=338691 ++ // DONE: Implement proper SCALAR parameter handling (doWait variable) ++ // which is/was not blocking in the original program. ++ // note: multi-byte input is not supported here. ++ ++ char c='\0'; //initialize is never a bad idea... ++ ++ int fd=fileno(stdin); ++#ifndef _MSC_VER ++ struct termios orig, get; ++#endif ++ // Get terminal setup to revert to it at end. ++#ifndef _MSC_VER ++ (void)tcgetattr(fd, &orig); ++ // New terminal setup, non-canonical. ++ get.c_lflag = ISIG; ++#endif ++ if (doWait) ++ { ++ // will wait for a character ++#ifndef _MSC_VER ++ get.c_cc[VTIME]=0; ++ get.c_cc[VMIN]=1; ++ (void)tcsetattr(fd, TCSANOW, &get); ++#endif ++ cin.get(c); ++ } ++ else ++ { ++ // will not wait, but return EOF or next character in terminal buffer if present ++#ifndef _MSC_VER ++ get.c_cc[VTIME]=0; ++ get.c_cc[VMIN]=0; ++ (void)tcsetattr(fd, TCSANOW, &get); ++#endif ++ //the trick is *not to use C++ functions here. cin.get would wait.* ++ c=std::fgetc(stdin); ++ //and to convert EOF to null (otherwise GDL may exit if not compiled with ++ //[lib][n]curses) ++ if(c==EOF) c='\0'; ++ } ++ ++ // Restore original terminal settings. ++#ifndef _MSC_VER ++ (void)tcsetattr(fd, TCSANOW, &orig); ++#endif ++#if defined(HAVE_LIBREADLINE) ++ rl_deprep_terminal (); ++#endif ++ ++ DStringGDL* res = new DStringGDL( DString( i2s( c))); ++ ++ return res; ++ ++ } ++ ++ ++ BaseGDL* temporary( EnvT* e) ++ { ++ SizeT nParam=e->NParam(1); ++ ++ BaseGDL** p0 = &e->GetParDefined( 0); ++ ++ BaseGDL* ret = *p0; ++ ++ *p0 = NULL; // make parameter undefined ++ return ret; ++ } ++ ++ BaseGDL* memory( EnvT* e) ++ { ++ SizeT nParam=e->NParam( 0); ++ ++ BaseGDL* ret; ++ bool kw_l64 = e->KeywordSet(e->KeywordIx("L64")); ++ // TODO: IDL-doc mentions about automatically switching to L64 if needed ++ ++ if (e->KeywordSet(e->KeywordIx("STRUCTURE"))) ++ { ++ // returning structure ++ if (kw_l64) ++ { ++ ret = new DStructGDL("IDL_MEMORY64"); ++ DStructGDL* retStru = static_cast(ret); ++ (retStru->GetTag(retStru->Desc()->TagIndex("CURRENT")))->InitFrom( DLong64GDL(MemStats::GetCurrent())); ++ (retStru->GetTag(retStru->Desc()->TagIndex("NUM_ALLOC")))->InitFrom( DLong64GDL(MemStats::GetNumAlloc())); ++ (retStru->GetTag(retStru->Desc()->TagIndex("NUM_FREE")))->InitFrom( DLong64GDL(MemStats::GetNumFree())); ++ (retStru->GetTag(retStru->Desc()->TagIndex("HIGHWATER")))->InitFrom( DLong64GDL(MemStats::GetHighWater())); ++ } ++ else ++ { ++ ret = new DStructGDL("IDL_MEMORY"); ++ DStructGDL* retStru = static_cast(ret); ++ (retStru->GetTag(retStru->Desc()->TagIndex("CURRENT")))->InitFrom( DLongGDL(MemStats::GetCurrent())); ++ (retStru->GetTag(retStru->Desc()->TagIndex("NUM_ALLOC")))->InitFrom( DLongGDL(MemStats::GetNumAlloc())); ++ (retStru->GetTag(retStru->Desc()->TagIndex("NUM_FREE")))->InitFrom( DLongGDL(MemStats::GetNumFree())); ++ (retStru->GetTag(retStru->Desc()->TagIndex("HIGHWATER")))->InitFrom( DLongGDL(MemStats::GetHighWater())); ++ } ++ } ++ else ++ { ++ bool kw_current = e->KeywordSet(e->KeywordIx("CURRENT")); ++ bool kw_num_alloc = e->KeywordSet(e->KeywordIx("NUM_ALLOC")); ++ bool kw_num_free = e->KeywordSet(e->KeywordIx("NUM_FREE")); ++ bool kw_highwater = e->KeywordSet(e->KeywordIx("HIGHWATER")); ++ ++ // Following the IDL documentation: mutually exclusive keywords ++ // IDL behaves different, incl. segfaults with selected kw combinations ++ if (kw_current + kw_num_alloc + kw_num_free + kw_highwater > 1) ++ e->Throw("CURRENT, NUM_ALLOC, NUM_FREE & HIGHWATER keywords" ++ " are mutually exclusive"); ++ ++ if (kw_current) ++ { ++ if (kw_l64) ret = new DLong64GDL(MemStats::GetCurrent()); ++ else ret = new DLongGDL(MemStats::GetCurrent()); ++ } ++ else if (kw_num_alloc) ++ { ++ if (kw_l64) ret = new DLong64GDL(MemStats::GetNumAlloc()); ++ else ret = new DLongGDL(MemStats::GetNumAlloc()); ++ } ++ else if (kw_num_free) ++ { ++ if (kw_l64) ret = new DLong64GDL(MemStats::GetNumFree()); ++ else ret = new DLongGDL(MemStats::GetNumFree()); ++ } ++ else if (kw_highwater) ++ { ++ if (kw_l64) ret = new DLong64GDL(MemStats::GetHighWater()); ++ else ret = new DLongGDL(MemStats::GetHighWater()); ++ } ++ else ++ { ++ // returning 4-element array ++ if (kw_l64) ++ { ++ ret = new DLong64GDL(dimension(4)); ++ (*static_cast(ret))[0] = MemStats::GetCurrent(); ++ (*static_cast(ret))[1] = MemStats::GetNumAlloc(); ++ (*static_cast(ret))[2] = MemStats::GetNumFree(); ++ (*static_cast(ret))[3] = MemStats::GetHighWater(); ++ } ++ else ++ { ++ ret = new DLongGDL(dimension(4)); ++ (*static_cast(ret))[0] = MemStats::GetCurrent(); ++ (*static_cast(ret))[1] = MemStats::GetNumAlloc(); ++ (*static_cast(ret))[2] = MemStats::GetNumFree(); ++ (*static_cast(ret))[3] = MemStats::GetHighWater(); ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++ inline DByte StrCmp( const string& s1, const string& s2, DLong n) ++ { ++ if( n <= 0) return 1; ++ if( s1.substr(0,n) == s2.substr(0,n)) return 1; ++ return 0; ++ } ++ inline DByte StrCmp( const string& s1, const string& s2) ++ { ++ if( s1 == s2) return 1; ++ return 0; ++ } ++ inline DByte StrCmpFold( const string& s1, const string& s2, DLong n) ++ { ++ if( n <= 0) return 1; ++ if( StrUpCase( s1.substr(0,n)) == StrUpCase(s2.substr(0,n))) return 1; ++ return 0; ++ } ++ inline DByte StrCmpFold( const string& s1, const string& s2) ++ { ++ if( StrUpCase( s1) == StrUpCase(s2)) return 1; ++ return 0; ++ } ++ ++ BaseGDL* strcmp_fun( EnvT* e) ++ { ++ SizeT nParam=e->NParam(2); ++ ++ DStringGDL* s0 = static_cast( e->GetParAs< DStringGDL>( 0)); ++ DStringGDL* s1 = static_cast( e->GetParAs< DStringGDL>( 1)); ++ ++ DLongGDL* l2 = NULL; ++ if( nParam > 2) ++ { ++ l2 = static_cast( e->GetParAs< DLongGDL>( 2)); ++ } ++ ++ static int foldIx = e->KeywordIx( "FOLD_CASE"); ++ bool fold = e->KeywordSet( foldIx ); ++ ++ if( s0->Scalar() && s1->Scalar()) ++ { ++ if( l2 == NULL) ++ { ++ if( fold) ++ return new DByteGDL( StrCmpFold( (*s0)[0], (*s1)[0])); ++ else ++ return new DByteGDL( StrCmp( (*s0)[0], (*s1)[0])); ++ } ++ else ++ { ++ DByteGDL* res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); ++ SizeT nEl = l2->N_Elements(); ++ if( fold) ++ for( SizeT i=0; iScalar()) ++ { ++ DByteGDL* res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); ++ SizeT nEl = s1->N_Elements(); ++ if( fold) ++ for( SizeT i=0; iScalar()) ++ { ++ DByteGDL* res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); ++ SizeT nEl = s0->N_Elements(); ++ if( fold) ++ for( SizeT i=0; iN_Elements() <= s1->N_Elements()) ++ { ++ res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); ++ nEl = s0->N_Elements(); ++ } ++ else ++ { ++ res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); ++ nEl = s1->N_Elements(); ++ } ++ if( fold) ++ for( SizeT i=0; iScalar(); ++ if( s0->Scalar()) ++ { ++ if( l2Scalar || s1->N_Elements() <= l2->N_Elements()) ++ { ++ res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); ++ nEl = s1->N_Elements(); ++ } ++ else ++ { ++ res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); ++ nEl = l2->N_Elements(); ++ } ++ if( fold) ++ for( SizeT i=0; iScalar()) ++ { ++ if( l2Scalar || s0->N_Elements() <= l2->N_Elements()) ++ { ++ res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); ++ nEl = s0->N_Elements(); ++ } ++ else ++ { ++ res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); ++ nEl = l2->N_Elements(); ++ } ++ if( fold) ++ for( SizeT i=0; iN_Elements() <= s1->N_Elements()) ++ { ++ res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); ++ nEl = s0->N_Elements(); ++ } ++ else ++ { ++ res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); ++ nEl = s1->N_Elements(); ++ } ++ else ++ { ++ if( s0->N_Elements() <= s1->N_Elements()) ++ if( s0->N_Elements() <= l2->N_Elements()) ++ { ++ res = new DByteGDL( s0->Dim(), BaseGDL::NOZERO); ++ nEl = s0->N_Elements(); ++ } ++ else ++ { ++ res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); ++ nEl = l2->N_Elements(); ++ } ++ else ++ if( s1->N_Elements() <= l2->N_Elements()) ++ { ++ res = new DByteGDL( s1->Dim(), BaseGDL::NOZERO); ++ nEl = s1->N_Elements(); ++ } ++ else ++ { ++ res = new DByteGDL( l2->Dim(), BaseGDL::NOZERO); ++ nEl = l2->N_Elements(); ++ } ++ } ++ if( fold) ++ for( SizeT i=0; i 'Z')) ++ e->Throw( "Illegal tag name: "+name+"."); ++ for( SizeT i=1; i 'Z') && ++ (n[i] < '0' || n[i] > '9')) ++ e->Throw( "Illegal tag name: "+name+"."); ++ } ++ return n; ++ } ++ ++ BaseGDL* create_struct( EnvT* e) ++ { ++ static int nameIx = e->KeywordIx( "NAME" ); ++ DString name = "$truct"; ++ if( e->KeywordPresent( nameIx)) { ++ // Check if name exists, if not then treat as unnamed ++ if (e->GetKW( nameIx) != NULL) ++ e->AssureStringScalarKW( nameIx, name); ++ } ++ ++ if( name != "$truct") // named struct ++ { ++ name = StrUpCase( name); ++ ++ SizeT nParam=e->NParam(); ++ ++ if( nParam == 0) ++ { ++ DStructDesc* desc = ++ e->Interpreter()->GetStruct( name, e->CallingNode()); ++ ++ dimension dim( 1); ++ return new DStructGDL( desc, dim); ++ } ++ ++ DStructDesc* nStructDesc; ++ auto_ptr nStructDescGuard; ++ ++ DStructDesc* oStructDesc= ++ FindInStructList( structList, name); ++ ++ if( oStructDesc == NULL || oStructDesc->NTags() > 0) ++ { ++ // not defined at all yet (-> define now) ++ // or completely defined (-> define now and check equality) ++ nStructDesc= new DStructDesc( name); ++ ++ // guard it ++ nStructDescGuard.reset( nStructDesc); ++ } ++ else ++ { ++ // NTags() == 0 ++ // not completely defined (only name in list) ++ nStructDesc= oStructDesc; ++ } ++ ++ // the instance variable ++ // dimension dim( 1); ++ // DStructGDL* instance = new DStructGDL( nStructDesc, dim); ++ DStructGDL* instance = new DStructGDL( nStructDesc); ++ auto_ptr instance_guard(instance); ++ ++ for( SizeT p=0; pGetParDefined( p); ++ DStructGDL* parStruct = dynamic_cast( par); ++ if( parStruct != NULL) ++ { ++ // add struct ++ if( !parStruct->Scalar()) ++ e->Throw("Expression must be a scalar in this context: "+ ++ e->GetParString( p)); ++ ++ DStructDesc* desc = parStruct->Desc(); ++ for( SizeT t=0; t< desc->NTags(); ++t) ++ { ++ instance->NewTag( desc->TagName( t), ++ parStruct->GetTag( t)->Dup()); ++ } ++ } ++ else ++ { ++ // add tag value pair ++ DStringGDL* tagNames = e->GetParAs( p); ++ SizeT nTags = tagNames->N_Elements(); ++ ++ SizeT tagStart = p+1; ++ SizeT tagEnd = p+nTags; ++ if( tagEnd >= nParam) ++ e->Throw( "Incorrect number of arguments."); ++ ++ do{ ++ ++p; ++ BaseGDL* value = e->GetParDefined( p); ++ ++ // add ++ instance->NewTag( TagName( e, (*tagNames)[ p-tagStart]), ++ value->Dup()); ++ } ++ while( pAssureIdentical(nStructDesc); ++ instance->DStructGDL::SetDesc(oStructDesc); ++ //delete nStructDesc; // auto_ptr ++ } ++ } ++ else ++ { ++ // release from guard (if not NULL) ++ nStructDescGuard.release(); ++ // insert into struct list ++ structList.push_back(nStructDesc); ++ } ++ ++ instance_guard.release(); ++ return instance; ++ } ++ else ++ { // unnamed struc ++ ++ // Handle case of single structure parameter ++ SizeT nParam; ++ nParam = e->NParam(1); ++ BaseGDL* par = e->GetParDefined( 0); ++ DStructGDL* parStruct = dynamic_cast( par); ++ if (nParam != 1 || parStruct == NULL) ++ nParam=e->NParam(2); ++ ++ DStructDesc* nStructDesc = new DStructDesc( "$truct"); ++ // instance takes care of nStructDesc since it is unnamed ++ // dimension dim( 1); ++ // DStructGDL* instance = new DStructGDL( nStructDesc, dim); ++ DStructGDL* instance = new DStructGDL( nStructDesc); ++ auto_ptr instance_guard(instance); ++ ++ for( SizeT p=0; pGetParDefined( p); ++ DStructGDL* parStruct = dynamic_cast( par); ++ if( parStruct != NULL) ++ { ++ // add struct ++ if( !parStruct->Scalar()) ++ e->Throw("Expression must be a scalar in this context: "+ ++ e->GetParString( p)); ++ ++ DStructDesc* desc = parStruct->Desc(); ++ for( SizeT t=0; t< desc->NTags(); ++t) ++ { ++ instance->NewTag( desc->TagName( t), ++ parStruct->GetTag( t)->Dup()); ++ } ++ ++p; ++ } ++ else ++ { ++ // add tag value pair ++ DStringGDL* tagNames = e->GetParAs( p); ++ SizeT nTags = tagNames->N_Elements(); ++ ++ SizeT tagStart = p+1; ++ SizeT tagEnd = p+nTags; ++ if( tagEnd >= nParam) ++ e->Throw( "Incorrect number of arguments."); ++ ++ for(++p; p<=tagEnd; ++p) ++ { ++ BaseGDL* value = e->GetParDefined( p); ++ ++ // add ++ instance->NewTag( TagName( e, (*tagNames)[ p-tagStart]), ++ value->Dup()); ++ } ++ } ++ } ++ ++ instance_guard.release(); ++ return instance; ++ } ++ } ++ ++ BaseGDL* rotate( EnvT* e) ++ { ++ e->NParam(2); ++ BaseGDL* p0 = e->GetParDefined( 0); ++ ++ if( p0->Rank() == 0) ++ e->Throw( "Expression must be an array in this context: " + e->GetParString( 0)); ++ ++ if( p0->Rank() != 1 && p0->Rank() != 2) ++ e->Throw( "Only 1 or 2 dimensions allowed: " + e->GetParString( 0)); ++ ++ if( p0->Type() == GDL_STRUCT) ++ e->Throw( "STRUCT expression not allowed in this context: "+ ++ e->GetParString( 0)); ++ ++ DLong dir; ++ e->AssureLongScalarPar( 1, dir); ++ ++ return p0->Rotate( dir); ++ } ++ ++ // SA: based on the code of rotate() (above) ++ BaseGDL* reverse( EnvT* e) ++ { ++ e->NParam(1); ++ BaseGDL* p0 = e->GetParDefined(0); ++ if (p0->Rank() == 0) return p0->Dup(); ++ ++ DLong dim = 1; ++ if (e->GetPar(1) != NULL) ++ e->AssureLongScalarPar(1, dim); ++ if (p0->Rank() != 0 && (dim > p0->Rank() || dim < 1)) ++ e->Throw("Subscript_index must be positive and less than or equal to number of dimensions."); ++ ++ BaseGDL* ret; ++ // IDL doc states that OVERWRITE is ignored for one- or two-dim. arrays ++ // but it seems to behave differently ++ // if (p0->Rank() > 2 && e->KeywordSet("OVERWRITE") && e->GlobalPar(0)) ++ if (e->KeywordSet("OVERWRITE")) ++ { ++ p0->Reverse(dim-1); ++ bool stolen = e->StealLocalPar( 0); ++ if( !stolen) e->GetPar(0) = NULL; ++ return p0; ++ } ++ else ret = p0->DupReverse(dim - 1); ++ return ret; ++ } ++ ++ // SA: parse_url based on the PHP parse_url() function code ++ // by Jim Winstead / The PHP Group (PHP license v. 3.01) ++ // (http://svn.php.net/viewvc/php/php-src/trunk/ext/standard/url.c) ++ // PHP is free software available at http://www.php.net/software/ ++ // ++ // notes: ++ // - IDL does not support IPv6 URLs, GDL does ++ // - IDL includes characters after '#' in the QUERY part, GDL ++ // just skips them and issues a warning (perhaps not needed) ++ // - IDL preserves controll characters in URLs, GDL preserves ++ // them as well but a warning is issued ++ // - IDL sets 80 as a default value for PORT, even if the url has ++ // an ftp:// schema indicated - GDL does not have any default value ++ // - IDL excludes the leading "/" from the path, GDL preserves it ++ // ... these differences seem just rational for me but please do change ++ // it if IDL-compatibility would be beneficial for any reason here ++ ++ BaseGDL* parse_url(EnvT* env) ++ { ++ // sanity check for number of parameters ++ SizeT nParam = env->NParam(); ++ ++ // 1-nd argument : the url string ++ DString url; ++ env->AssureScalarPar(0, url); ++ ++ // sanity check for controll characters ++ string::iterator it; ++ for (it = url.begin(); it < url.end(); it++) if (iscntrl(*it)) ++ { ++ Warning("PARSE_URL: URL contains a control character"); ++ break; ++ } ++ ++ // creating the output anonymous structure ++ DStructDesc* urlstru_desc = new DStructDesc("$truct"); ++ SpDString aString; ++ urlstru_desc->AddTag("SCHEME", &aString); ++ static size_t ixSCHEME = 0; ++ urlstru_desc->AddTag("USERNAME", &aString); ++ urlstru_desc->AddTag("PASSWORD", &aString); ++ urlstru_desc->AddTag("HOST", &aString); ++ urlstru_desc->AddTag("PORT", &aString); ++ static size_t ixPORT = 4; ++ urlstru_desc->AddTag("PATH", &aString); ++ urlstru_desc->AddTag("QUERY", &aString); ++ DStructGDL* urlstru = new DStructGDL(urlstru_desc, dimension()); ++ auto_ptr urlstru_guard(urlstru); ++ ++ // parsing the URL ++ char const *str = url.c_str(); ++ size_t length = url.length(); ++ char port_buf[6]; ++ char const *s, *e, *p, *pp, *ue; ++ ++ s = str; ++ ue = s + length; ++ ++ // parsing scheme ++ if ((e = (const char*)memchr(s, ':', length)) && (e - s)) ++ { ++ // validating scheme ++ p = s; ++ while (p < e) ++ { ++ // scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] ++ if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') ++ { ++ if (e + 1 < ue) goto parse_port; ++ else goto just_path; ++ } ++ p++; ++ } ++ if (*(e + 1) == '\0') ++ { ++ // only scheme is available ++ urlstru->InitTag("SCHEME", DStringGDL(string(s, (e - s)))); ++ goto end; ++ } ++ // schemas without '/' (like mailto: and zlib:) ++ if (*(e+1) != '/') ++ { ++ // check if the data we get is a port this allows us to correctly parse things like a.com:80 ++ p = e + 1; ++ while (isdigit(*p)) p++; ++ if ((*p == '\0' || *p == '/') && (p - e) < 7) goto parse_port; ++ urlstru->InitTag("SCHEME", DStringGDL(string(s, (e - s)))); ++ length -= ++e - s; ++ s = e; ++ goto just_path; ++ } ++ else ++ { ++ urlstru->InitTag("SCHEME", DStringGDL(string(s, (e - s)))); ++ if (*(e+2) == '/') ++ { ++ s = e + 3; ++ if (!strncasecmp("file", ++ (*static_cast(urlstru->GetTag(ixSCHEME)))[0].c_str(), ++ sizeof("file") ++ )) ++ { ++ if (*(e + 3) == '/') ++ { ++ // support windows drive letters as in: file:///c:/somedir/file.txt ++ if (*(e + 5) == ':') s = e + 4; ++ goto nohost; ++ } ++ } ++ } ++ else ++ { ++ if (!strncasecmp("file", ++ (*static_cast(urlstru->GetTag(ixSCHEME)))[0].c_str(), ++ sizeof("file")) ++ ) ++ { ++ s = e + 1; ++ goto nohost; ++ } ++ else ++ { ++ length -= ++e - s; ++ s = e; ++ goto just_path; ++ } ++ } ++ } ++ } ++ else if (e) ++ { ++ // no scheme, look for port ++ parse_port: ++ p = e + 1; ++ pp = p; ++ while (pp-p < 6 && isdigit(*pp)) pp++; ++ if (pp-p < 6 && (*pp == '/' || *pp == '\0')) ++ { ++ memcpy(port_buf, p, (pp-p)); ++ port_buf[pp-p] = '\0'; ++ urlstru->InitTag("PORT", DStringGDL(port_buf)); ++ } ++ else goto just_path; ++ } ++ else ++ { ++ just_path: ++ ue = s + length; ++ goto nohost; ++ } ++ e = ue; ++ if (!(p = (const char*)memchr(s, '/', (ue - s)))) ++ { ++ if ((p = (const char*)memchr(s, '?', (ue - s)))) e = p; ++ else if ((p = (const char*)memchr(s, '#', (ue - s)))) e = p; ++ } ++ else e = p; ++ // check for login and password ++ { ++ size_t pos; ++ if ((pos = string(s, e - s).find_last_of("@")) != string::npos) ++ { ++ p = s + pos; ++ if ((pp = (const char*)memchr(s, ':', (p-s)))) ++ { ++ if ((pp-s) > 0) urlstru->InitTag("USERNAME", DStringGDL(string(s, (pp - s)))); ++ pp++; ++ if (p-pp > 0) urlstru->InitTag("PASSWORD", DStringGDL(string(pp, (p - pp)))); ++ } ++ else urlstru->InitTag("USERNAME", DStringGDL(string(s, (p - s)))); ++ s = p + 1; ++ } ++ } ++ // check for port ++ if (*s == '[' && *(e-1) == ']') p = s; // IPv6 embedded address ++ else for(p = e; *p != ':' && p >= s; p--); // memrchr is a GNU extension ++ if (p >= s && *p == ':') ++ { ++ if ((*static_cast(urlstru->GetTag(ixPORT)))[0].length() == 0) ++ { ++ p++; ++ if (e-p > 5) env->Throw("port cannot be longer then 5 characters"); ++ else if (e - p > 0) ++ { ++ memcpy(port_buf, p, (e-p)); ++ port_buf[e-p] = '\0'; ++ urlstru->InitTag("PORT", DStringGDL(port_buf)); ++ } ++ p--; ++ } ++ } ++ else p = e; ++ // check if we have a valid host, if we don't reject the string as url ++ if ((p-s) < 1) env->Throw("invalid host"); ++ urlstru->InitTag("HOST", DStringGDL(string(s, (p - s)))); ++ if (e == ue) goto end; ++ s = e; ++ nohost: ++ if ((p = (const char*)memchr(s, '?', (ue - s)))) ++ { ++ pp = strchr(s, '#'); ++ if (pp && pp < p) ++ { ++ p = pp; ++ pp = strchr(pp+2, '#'); ++ } ++ if (p - s) urlstru->InitTag("PATH", DStringGDL(string(s, (p - s)))); ++ if (pp) ++ { ++ if (pp - ++p) urlstru->InitTag("QUERY", DStringGDL(string(p, (pp - p)))); ++ p = pp; ++ goto label_parse; ++ } ++ else if (++p - ue) urlstru->InitTag("QUERY", DStringGDL(string(p, (ue - p)))); ++ } ++ else if ((p = (const char*)memchr(s, '#', (ue - s)))) ++ { ++ if (p - s) urlstru->InitTag("PATH", DStringGDL(string(s, (p - s)))); ++ label_parse: ++ p++; ++ if (ue - p) Warning("PARSE_URL: URL fragment left out: #" + string(p, (ue-p))); ++ } ++ else urlstru->InitTag("PATH", DStringGDL(string(s, (ue - s)))); ++ end: ++ ++ // returning the result ++ urlstru_guard.release(); ++ return urlstru; ++ } ++ ++ BaseGDL* locale_get(EnvT* e) ++ { ++#ifdef HAVE_LOCALE_H ++ ++ // make GDL inherit the calling process locale ++ setlocale(LC_ALL, ""); ++ // note doen the inherited locale ++ DStringGDL *locale = new DStringGDL(setlocale(LC_CTYPE, NULL)); ++ // return to the C locale ++ setlocale(LC_ALL, "C"); ++ ++ return locale; ++#else ++ e->Throw("OS does not provide locale information"); ++#endif ++ } ++ ++ // SA: relies on the contents of the lib::command_line_args vector ++ // defined and filled with data (pointers) in gdl.cpp ++ BaseGDL* command_line_args_fun(EnvT* e) ++ { ++#ifdef PYTHON_MODULE ++ e->Throw("no command line arguments available (GDL built as a Python module)"); ++#else ++ static int countIx = e->KeywordIx("COUNT"); ++ extern std::vector command_line_args; ++ ++ // setting the COUNT keyword value ++ if (e->KeywordPresent(countIx)) ++ { ++ e->AssureGlobalKW(countIx); ++ e->SetKW(countIx, new DLongGDL(command_line_args.size())); ++ } ++ ++ // returning empty string or an array of arguments ++ if (command_line_args.empty()) return new DStringGDL(""); ++ else ++ { ++ BaseGDL* ret = new DStringGDL(dimension(command_line_args.size())); ++ for (size_t i = 0; i < command_line_args.size(); i++) ++ (*static_cast(ret))[i] = command_line_args[i]; ++ return ret; ++ } ++#endif ++ } ++ ++ // SA: relies in the uname() from libc (must be there if POSIX) ++ BaseGDL* get_login_info( EnvT* e) ++ { ++ // getting the info ++#ifdef _MSC_VER ++ #define MAX_TCHAR_BUF 256 ++ ++ char login[MAX_TCHAR_BUF]; ++ char info[MAX_TCHAR_BUF]; ++ ++ DWORD N_TCHAR = MAX_TCHAR_BUF; ++ ++ #ifdef _UNICODE ++ TCHAR t_buf[MAX_TCHAR_BUF]; ++ GetUserName(t_buf, &N_TCHAR); ++ WideCharToMultiByte(CP_ACP, 0, t_buf, N_TCHAR, login, N_TCHAR, NULL, NULL); ++ GetComputerName( t_buf, &N_TCHAR ); ++ WideCharToMultiByte(CP_ACP, 0, t_buf, N_TCHAR, info, N_TCHAR, NULL, NULL); ++ #else ++ GetUserName(login, &N_TCHAR); ++ GetComputerName(info, &N_TCHAR); ++ #endif ++#else ++ char* login = getlogin(); ++ if (login == NULL) e->Throw("Failed to get user name from the OS"); ++ struct utsname info; ++ if (0 != uname(&info)) e->Throw("Failed to get machine name from the OS"); ++#endif ++ // creating the output anonymous structure ++ DStructDesc* stru_desc = new DStructDesc("$truct"); ++ SpDString aString; ++ stru_desc->AddTag("MACHINE_NAME", &aString); ++ stru_desc->AddTag("USER_NAME", &aString); ++ DStructGDL* stru = new DStructGDL(stru_desc, dimension()); ++ ++ // returning the info ++ stru->InitTag("USER_NAME", DStringGDL(login)); ++#ifdef _MSC_VER ++ stru->InitTag("MACHINE_NAME", DStringGDL(info)); ++#else ++ stru->InitTag("MACHINE_NAME", DStringGDL(info.nodename)); ++#endif ++ return stru; ++ } ++ ++ // SA: base64 logic in base64.hpp, based on code by Bob Withers (consult base64.hpp) ++ BaseGDL* idl_base64(EnvT* e) ++ { ++ BaseGDL* p0 = e->GetPar(0); ++ if (p0 != NULL) ++ { ++ if (p0->Rank() == 0 && p0->Type() == GDL_STRING) ++ { ++ // decoding ++ string* str = &((*static_cast(p0))[0]); ++ if (str->length() == 0) return new DByteGDL(0); ++ if (str->length() % 4 != 0) ++ e->Throw("Input string length must be a multiple of 4"); ++ unsigned int retlen = base64::decodeSize(*str); ++ if (retlen == 0 || retlen > str->length()) e->Throw("No data in the input string"); ++ DByteGDL* ret = new DByteGDL(dimension(retlen)); ++ if (!base64::decode(*str, (char*)&((*ret)[0]), ret->N_Elements())) ++ e->Throw("Base64 decoder failed"); ++ return ret; ++ } ++ if (p0->Rank() >= 1 && p0->Type() == GDL_BYTE) ++ { ++ // encoding ++ return new DStringGDL( ++ base64::encode((char*)&(*static_cast(p0))[0], p0->N_Elements()) ++ ); ++ } ++ } ++ e->Throw("Expecting string or byte array as a first parameter"); ++ } ++ ++ BaseGDL* get_drive_list(EnvT* e) ++ { ++ if (e->KeywordPresent(0)) e->SetKW(0, new DLongGDL(0)); ++ return new DStringGDL(""); ++ } ++ ++ // note: changes here MUST be reflected in scope_varfetch_reference() as well ++ // because DLibFun of this function is used for scope_varfetch_reference() the keyword ++ // indices must match ++ BaseGDL* scope_varfetch_value( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ ++ EnvStackT& callStack = e->Interpreter()->CallStack(); ++// DLong curlevnum = callStack.size()-1; ++// 'e' is not on the stack ++ DLong curlevnum = callStack.size(); ++ ++// static int variablesIx = e->KeywordIx( "VARIABLES" ); ++ static int levelIx = e->KeywordIx( "LEVEL" ); ++ ++ DLongGDL* level = e->IfDefGetKWAs( levelIx); ++ ++ DLong desiredlevnum = 0; ++ ++ if (level != NULL) ++ desiredlevnum = (*level)[0]; ++ ++ if (desiredlevnum <= 0) desiredlevnum += curlevnum; ++ if (desiredlevnum < 1) desiredlevnum = 1; ++ else if (desiredlevnum > curlevnum) desiredlevnum = curlevnum; ++ ++ DSubUD* pro = static_cast(callStack[desiredlevnum-1]->GetPro()); ++ ++ SizeT nVar = pro->Size(); // # var in GDL for desired level ++ int nKey = pro->NKey(); ++ ++ DString varName; ++ ++ e->AssureScalarPar( 0, varName); ++ varName = StrUpCase( varName); ++ ++ int xI = pro->FindVar( varName); ++ if (xI != -1) ++ { ++// BaseGDL*& par = ((EnvT*)(callStack[desiredlevnum-1]))->GetPar( xI); ++ BaseGDL*& par = callStack[desiredlevnum-1]->GetKW( xI); ++ ++ if( par == NULL) ++ e->Throw( "Variable is undefined: " + varName); ++ ++ return par->Dup(); ++ } ++ ++ e->Throw( "Variable not found: " + varName); ++ return new DLongGDL(0); // compiler shut-up ++ } ++ ++ // this routine is special, only called as an l-function (from FCALL_LIB::LEval()) ++ // it MUST use an EnvT set up for scope_varfetch_value ++ BaseGDL** scope_varfetch_reference( EnvT* e) ++ { ++ SizeT nParam=e->NParam(); ++ ++ EnvStackT& callStack = e->Interpreter()->CallStack(); ++// DLong curlevnum = callStack.size()-1; ++// 'e' is not on the stack ++ DLong curlevnum = callStack.size(); ++ ++// static int variablesIx = e->KeywordIx( "VARIABLES" ); ++ static int levelIx = e->KeywordIx( "LEVEL" ); ++ ++ DLongGDL* level = e->IfDefGetKWAs( levelIx); ++ ++ DLong desiredlevnum = 0; ++ ++ if (level != NULL) ++ desiredlevnum = (*level)[0]; ++ ++ if (desiredlevnum <= 0) desiredlevnum += curlevnum; ++ if (desiredlevnum < 1) desiredlevnum = 1; ++ else if (desiredlevnum > curlevnum) desiredlevnum = curlevnum; ++ ++ DSubUD* pro = static_cast(callStack[desiredlevnum-1]->GetPro()); ++ ++ SizeT nVar = pro->Size(); // # var in GDL for desired level ++ int nKey = pro->NKey(); ++ ++ DString varName; ++ ++ e->AssureScalarPar( 0, varName); ++ varName = StrUpCase( varName); ++ int xI = pro->FindVar( varName); ++ if (xI != -1) ++ { ++// BaseGDL*& par = ((EnvT*)(callStack[desiredlevnum-1]))->GetPar( xI); ++ BaseGDL*& par = callStack[desiredlevnum-1]->GetKW( xI); ++ ++// if( par == NULL) ++// e->Throw( "Variable is undefined: " + varName); ++ ++ return ∥ ++ } ++ ++ e->Throw( "LVariable not found: " + varName); ++ return NULL; // compiler shut-up ++ } ++ ++ ++} // namespace ++ +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_op_add.cpp gdl/src/basic_op_add.cpp +--- gdl-0.9.3/src/basic_op_add.cpp 1969-12-31 17:00:00.000000000 -0700 ++++ gdl/src/basic_op_add.cpp 2013-03-16 11:23:48.000000000 -0600 +@@ -0,0 +1,443 @@ ++/*************************************************************************** ++ basic_op_add.cpp - GDL add (+) operators ++ ------------------- ++ begin : July 22 2002 ++ copyright : (C) 2002 by Marc Schellens ++ email : m_schellens@users.sf.net ++***************************************************************************/ ++ ++/*************************************************************************** ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ ***************************************************************************/ ++ ++// to be included from datatypes.cpp ++#ifdef INCLUDE_BASIC_OP_CPP ++ ++// // header in datatypes.hpp ++// ++// //#include "datatypes.hpp" ++// //#include "dstructgdl.hpp" ++// //#include "arrayindex.hpp" ++// ++// //#include ++// #include "sigfpehandler.hpp" ++// ++// #ifdef _OPENMP ++// #include ++// #endif ++// ++// #include "typetraits.hpp" ++// ++// using namespace std; ++ ++ ++// ************************ ++// Add ++// ************************ ++ ++// also see Add...New operators (in basic_op_new.cpp) ++ ++// Adds right to itself, //C deletes right ++// right must always have more or same number of elements ++template ++BaseGDL* Data_::Add( BaseGDL* r) ++{ ++ ++ ++ Data_* right=static_cast(r); ++ ++ // ULong rEl=right->N_Elements(); ++ ULong nEl=N_Elements(); ++ // assert( rEl); ++ assert( nEl); ++ if( nEl == 1) ++ { ++ (*this)[0] += (*right)[0]; ++ return this; ++ } ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRight(&(*right)[0], nEl); ++ mThis += mRight; ++ return this; ++#else ++ ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] += (*right)[i]; ++ } //C delete right; ++ return this; ++#endif ++ ++} ++template ++BaseGDL* Data_::AddInv( BaseGDL* r) ++{ ++ assert( this->Type() != GDL_OBJ); // should never be called via this ++ return Add( r); // this needs to be modified ++} ++template<> ++BaseGDL* Data_::AddInv( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ // ULong rEl=right->N_Elements(); ++ ULong nEl=N_Elements(); ++ // assert( rEl); ++ assert( nEl); ++ if( nEl == 1) ++ { ++ (*this)[0] = (*right)[0] + (*this)[0]; ++ return this; ++ } ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] = (*right)[i] + (*this)[i]; ++ } //C delete right; ++ return this; ++} ++// invalid types ++DStructGDL* DStructGDL::Add( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++DStructGDL* DStructGDL::AddInv( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::Add( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::Add( BaseGDL* r) ++{ ++ // overload here ++ Data_* self; ++ DFun* plusOverload; ++ ++ ProgNodeP callingNode = interpreter->GetRetTree(); ++ ++ if( !Scalar()) ++ { ++ if( r->Type() == GDL_OBJ && r->Scalar()) ++ { ++ self = static_cast( r); ++ plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOPlus)); ++ if( plusOverload == NULL) ++ { ++ throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); ++ } ++ } ++ else ++ { ++ throw GDLException( callingNode, "Cannot apply operation to non-scalar datatype OBJECT.", true, false); ++ } ++ } ++ else ++ { ++ // Scalar() ++ self = static_cast( this); ++ plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOPlus)); ++ if( plusOverload == NULL) ++ { ++ if( r->Type() == GDL_OBJ && r->Scalar()) ++ { ++ self = static_cast( r); ++ plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOPlus)); ++ if( plusOverload == NULL) ++ { ++ throw GDLException(callingNode,"Cannot apply not overloaded operator to datatype OBJECT.",true, false); ++ } ++ } ++ else ++ { ++ throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); ++ } ++ } ++ } ++ ++ assert( self->Scalar()); ++ assert( plusOverload != NULL); ++ ++ // hidden SELF is counted as well ++ int nParSub = plusOverload->NPar(); ++ assert( nParSub >= 1); // SELF ++ if( nParSub < 3) // (SELF), LEFT, RIGHT ++ { ++ throw GDLException( callingNode, plusOverload->ObjectName() + ++ ": Incorrect number of arguments.", ++ false, false); ++ } ++ EnvUDT* newEnv; ++ Guard selfGuard; ++ BaseGDL* thisP; ++ // Dup() here is not optimal ++ // avoid at least for internal overload routines (which do/must not change SELF or r) ++ bool internalDSubUD = plusOverload->GetTree()->IsWrappedNode(); ++ if( internalDSubUD) ++ { ++ thisP = this; ++ newEnv= new EnvUDT( callingNode, plusOverload, &self); ++ newEnv->SetNextParUnchecked( &thisP); // LEFT parameter, as reference to prevent cleanup in newEnv ++ newEnv->SetNextParUnchecked( &r); // RVALUE parameter, as reference to prevent cleanup in newEnv ++ } ++ else ++ { ++ self = self->Dup(); ++ selfGuard.Init( self); ++ newEnv= new EnvUDT( callingNode, plusOverload, &self); ++ newEnv->SetNextParUnchecked( this->Dup()); // LEFT parameter, as value ++ newEnv->SetNextParUnchecked( r->Dup()); // RIGHT parameter, as value ++ } ++ ++ ++ // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack ++ StackGuard guard(interpreter->CallStack()); ++ ++ interpreter->CallStack().push_back( newEnv); ++ ++ // make the call ++ BaseGDL* res=interpreter->call_fun(static_cast(newEnv->GetPro())->GetTree()); ++ ++ if( !internalDSubUD && self != selfGuard.Get()) ++ { ++ // always put out warning first, in case of a later crash ++ Warning( "WARNING: " + plusOverload->ObjectName() + ++ ": Assignment to SELF detected (GDL session still ok)."); ++ // assignment to SELF -> self was deleted and points to new variable ++ // which it owns ++ selfGuard.Release(); ++ if( static_cast(self) != NullGDL::GetSingleInstance()) ++ selfGuard.Reset(self); ++ } ++ return res; ++} ++// difference from above: Order of parameters in call ++template<> ++BaseGDL* Data_::AddInv( BaseGDL* r) ++{ ++ if( r->Type() == GDL_OBJ && r->Scalar()) ++ { ++ return r->Add( this); // for right order of parameters ++ } ++ ++ // overload here ++ Data_* self; ++ DFun* plusOverload; ++ ++ ProgNodeP callingNode = interpreter->GetRetTree(); ++ ++ if( !Scalar()) ++ { ++ throw GDLException( callingNode, "Cannot apply operation to non-scalar datatype OBJECT.", true, false); ++ } ++ else ++ { ++ // Scalar() ++ self = static_cast( this); ++ plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOPlus)); ++ if( plusOverload == NULL) ++ { ++ throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); ++ } ++ } ++ ++ assert( self->Scalar()); ++ assert( plusOverload != NULL); ++ ++ // hidden SELF is counted as well ++ int nParSub = plusOverload->NPar(); ++ assert( nParSub >= 1); // SELF ++ if( nParSub < 3) // (SELF), LEFT, RIGHT ++ { ++ throw GDLException( callingNode, plusOverload->ObjectName() + ++ ": Incorrect number of arguments.", ++ false, false); ++ } ++ EnvUDT* newEnv; ++ Guard selfGuard; ++ BaseGDL* thisP; ++ // Dup() here is not optimal ++ // avoid at least for internal overload routines (which do/must not change SELF or r) ++ bool internalDSubUD = plusOverload->GetTree()->IsWrappedNode(); ++ if( internalDSubUD) ++ { ++ thisP = this; ++ newEnv= new EnvUDT( callingNode, plusOverload, &self); ++ // order different to Add ++ newEnv->SetNextParUnchecked( &r); // RVALUE parameter, as reference to prevent cleanup in newEnv ++ newEnv->SetNextParUnchecked( &thisP); // LEFT parameter, as reference to prevent cleanup in newEnv ++ } ++ else ++ { ++ self = self->Dup(); ++ selfGuard.Init( self); ++ newEnv= new EnvUDT( callingNode, plusOverload, &self); ++ // order different to Add ++ newEnv->SetNextParUnchecked( r->Dup()); // RIGHT parameter, as value ++ newEnv->SetNextParUnchecked( this->Dup()); // LEFT parameter, as value ++ } ++ ++ ++ // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack ++ StackGuard guard(interpreter->CallStack()); ++ ++ interpreter->CallStack().push_back( newEnv); ++ ++ // make the call ++ BaseGDL* res=interpreter->call_fun(static_cast(newEnv->GetPro())->GetTree()); ++ ++ if( !internalDSubUD && self != selfGuard.Get()) ++ { ++ // always put out warning first, in case of a later crash ++ Warning( "WARNING: " + plusOverload->ObjectName() + ++ ": Assignment to SELF detected (GDL session still ok)."); ++ // assignment to SELF -> self was deleted and points to new variable ++ // which it owns ++ selfGuard.Release(); ++ if( static_cast(self) != NullGDL::GetSingleInstance()) ++ selfGuard.Reset(self); ++ } ++ return res; ++} ++ ++template ++BaseGDL* Data_::AddS( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong nEl=N_Elements(); ++ assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ if( nEl == 1) ++ { ++ (*this)[0] += (*right)[0]; ++ return this; ++ } ++ Ty s = (*right)[0]; ++ // right->Scalar(s); ++ // dd += s; ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ mThis += s; ++ return this; ++#else ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] += s; ++ } //C delete right; ++ return this; ++#endif ++ ++} ++template<> ++BaseGDL* Data_::AddS( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong nEl=N_Elements(); ++ assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ if( nEl == 1) ++ { ++ (*this)[0] += (*right)[0]; ++ return this; ++ } ++ Ty s = (*right)[0]; ++ // right->Scalar(s); ++ // dd += s; ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] += s; ++ } //C delete right; ++ return this; ++} ++ ++template ++BaseGDL* Data_::AddInvS( BaseGDL* r) ++{ ++ return AddS( r); ++} ++template<> ++BaseGDL* Data_::AddInvS( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong nEl=N_Elements(); ++ assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ if( nEl == 1) ++ { ++ (*this)[0] = (*right)[0] + (*this)[0] ; ++ return this; ++ } ++ Ty s = (*right)[0]; ++ // right->Scalar(s); ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] = s + (*this)[i]; ++ } //C delete right; ++ return this; ++ ++} ++ ++// invalid types ++DStructGDL* DStructGDL::AddS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++DStructGDL* DStructGDL::AddInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::AddS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::AddS( BaseGDL* r) ++{ ++ return Add( r); ++} ++template<> ++BaseGDL* Data_::AddInvS( BaseGDL* r) ++{ ++ return AddInv( r); ++} ++ ++ ++//#include "instantiate_templates.hpp" ++ ++#endif diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_op.cpp gdl/src/basic_op.cpp --- gdl-0.9.3/src/basic_op.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/basic_op.cpp 2013-02-25 17:04:24.555181271 -0700 -@@ -1503,7 +1503,7 @@ ++++ gdl/src/basic_op.cpp 2013-03-21 14:04:04.242825801 -0600 +@@ -36,6 +36,11 @@ + + using namespace std; + ++#include "basic_op_add.cpp" ++#include "basic_op_sub.cpp" ++#include "basic_op_mult.cpp" ++#include "basic_op_div.cpp" ++ + // Not operation + // for integers + template +@@ -53,11 +58,12 @@ + // if( !nEl) throw GDLException("Variable is undefined."); + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { ++ { + #pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] = ~(*this)[i]; +- } return this; ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] = ~(*this)[i]; ++ } ++ return this; + } + // others + template<> +@@ -76,7 +82,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = ((*this)[i] == 0.0f)? 1.0f : 0.0f; + } return this; + } +@@ -95,7 +101,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = ((*this)[i] == 0.0)? 1.0 : 0.0; + } return this; + } +@@ -119,19 +125,19 @@ + } + DStructGDL* DStructGDL::NotOp() + { +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); + return this; + } + template<> + Data_* Data_::NotOp() + { +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); + return this; + } + template<> + Data_* Data_::NotOp() + { +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); + return this; + } + +@@ -153,7 +159,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = -(*this)[i]; + } return this; + } +@@ -205,7 +211,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] == 0)? 1 : 0; + } return res; + } +@@ -226,7 +232,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] == 0.0f)? 1 : 0; + } return res; + } +@@ -247,7 +253,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] == 0.0)? 1 : 0; + } return res; + } +@@ -267,7 +273,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] == "")? 1 : 0; + } return res; + } +@@ -287,7 +293,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i].real() == 0.0 && (*this)[i].imag() == 0.0)? 1 : 0; + } return res; + } +@@ -307,7 +313,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i].real() == 0.0 && (*this)[i].imag() == 0.0)? 1 : 0; + } return res; + } +@@ -329,7 +335,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i]--; + }} + template +@@ -347,7 +353,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i]++; + }} + // float +@@ -367,7 +373,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] -= 1.0; + }} + template<> +@@ -386,7 +392,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] += 1.0; + }} + // double +@@ -406,7 +412,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] -= 1.0; + }} + template<> +@@ -425,7 +431,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] += 1.0; + }} + // complex +@@ -445,7 +451,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] -= 1.0; + }} + template<> +@@ -464,7 +470,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] += 1.0; + }} + template<> +@@ -483,7 +489,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] -= 1.0; + }} + template<> +@@ -502,7 +508,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] += 1.0; + }} + // forbidden types +@@ -571,7 +577,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] == s); + } } + else if( StrictScalar(s)) +@@ -586,7 +592,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] == s); + } } + else if( rEl < nEl) +@@ -596,7 +602,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] == (*this)[i]); + } } + else // ( rEl >= nEl) +@@ -611,7 +617,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] == (*this)[i]); + } } + //C delete right; +@@ -726,7 +732,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] == s); + } } + else if( StrictScalar(s)) +@@ -741,7 +747,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] == s); + } } + else if( rEl < nEl) +@@ -751,7 +757,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] == (*this)[i]); + } } + else // ( rEl >= nEl) +@@ -766,7 +772,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] == (*this)[i]); + } } + //C delete right; +@@ -821,7 +827,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] != s); + } } + else if( StrictScalar(s)) +@@ -836,7 +842,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] != s); + } } + else if( rEl < nEl) +@@ -846,7 +852,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] != (*this)[i]); + } } + else // ( rEl >= nEl) +@@ -861,7 +867,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] != (*this)[i]); + } } + //C delete right; +@@ -976,7 +982,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] != s); + } } + else if( StrictScalar(s)) +@@ -991,7 +997,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] != s); + } } + else if( rEl < nEl) +@@ -1001,7 +1007,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] != (*this)[i]); + } } + else // ( rEl >= nEl) +@@ -1016,7 +1022,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] != (*this)[i]); + } } + //C delete right; +@@ -1071,7 +1077,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] <= s); + } } + else if( StrictScalar(s)) +@@ -1086,7 +1092,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] >= s); + } } + else if( rEl < nEl) +@@ -1096,7 +1102,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] >= (*this)[i]); + } } + else // ( rEl >= nEl) +@@ -1111,7 +1117,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] >= (*this)[i]); + } } + //C delete right; +@@ -1177,7 +1183,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] < s); + } } + else if( StrictScalar(s)) +@@ -1192,7 +1198,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] > s); + } } + else if( rEl < nEl) +@@ -1202,7 +1208,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] > (*this)[i]); + } } + else // ( rEl >= nEl) +@@ -1217,7 +1223,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] > (*this)[i]); + } } + //C delete right; +@@ -1283,7 +1289,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] >= s); + } } + else if( StrictScalar(s)) +@@ -1298,7 +1304,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] <= s); + } } + else if( rEl < nEl) +@@ -1308,7 +1314,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] <= (*this)[i]); + } } + else // ( rEl >= nEl) +@@ -1323,7 +1329,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] <= (*this)[i]); + } } + //C delete right; +@@ -1389,7 +1395,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*this)[i] > s); + } } + else if( StrictScalar(s)) +@@ -1404,7 +1410,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] < s); + } } + else if( rEl < nEl) +@@ -1414,7 +1420,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] < (*this)[i]); + } } + else // ( rEl >= nEl) +@@ -1429,7 +1435,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] < (*this)[i]); + } } + //C delete right; +@@ -1467,7 +1473,7 @@ + return NULL; + } + // MatrixOp +-// returns *this # *r, //C deletes itself and right ++// returns *this # *r, //C does not delete itself and right + template + Data_* Data_::MatrixOp( BaseGDL* r, bool transpose, bool transposeResult, bool strassen) + { +@@ -1503,8 +1509,8 @@ #pragma omp parallel if (nOp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nOp)) default(shared) { #pragma omp for - for( int colA=0; colA < nCol; colA++) // res dim 0 -+ for( SizeT colA=0; colA < nCol; colA++) // res dim 0 - for( SizeT rowB=0; rowB < nRow; rowB++) // res dim 1 +- for( SizeT rowB=0; rowB < nRow; rowB++) // res dim 1 ++ for( OMPInt colA=0; colA < nCol; colA++) // res dim 0 ++ for( OMPInt rowB=0; rowB < nRow; rowB++) // res dim 1 (*res)[ rowB * nCol + colA] += (*this)[colA] * (*right)[rowB]; } -@@ -1624,7 +1624,7 @@ + } +@@ -1624,13 +1630,13 @@ #pragma omp parallel if (nOp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nOp)) default(shared) { #pragma omp for - for( int colA=0; colA < nCol; ++colA) // res dim 0 -+ for( SizeT colA=0; colA < nCol; ++colA) // res dim 0 - for( SizeT rIx=0, rowBnCol=0; rIx < rIxEnd; +- for( SizeT rIx=0, rowBnCol=0; rIx < rIxEnd; ++ for( OMPInt colA=0; colA < nCol; ++colA) // res dim 0 ++ for( OMPInt rIx=0, rowBnCol=0; rIx < rIxEnd; rIx += nColEl, rowBnCol += nCol) // res dim 1 { -@@ -1641,7 +1641,7 @@ + Ty& resEl = (*res)[ rowBnCol + colA]; + resEl = 0;//(*this)[ colA] * (*right)[ rIx]; // initialization +- for( SizeT i=0; i < nColEl; ++i) ++ for( OMPInt i=0; i < nColEl; ++i) + resEl += (*this)[ i*nCol+colA] * (*right)[ rIx+i]; + } + } +@@ -1641,12 +1647,12 @@ #pragma omp parallel if (nOp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nOp)) default(shared) { #pragma omp for - for( int colA=0; colA < nCol; ++colA) // res dim 0 -+ for( SizeT colA=0; colA < nCol; ++colA) // res dim 0 - for( SizeT rIx=0, rowBnCol=0; rIx < nRow; ++rIx, rowBnCol += nCol) // res dim 1 +- for( SizeT rIx=0, rowBnCol=0; rIx < nRow; ++rIx, rowBnCol += nCol) // res dim 1 ++ for( OMPInt colA=0; colA < nCol; ++colA) // res dim 0 ++ for( OMPInt rIx=0, rowBnCol=0; rIx < nRow; ++rIx, rowBnCol += nCol) // res dim 1 { Ty& resEl = (*res)[ rowBnCol + colA]; -@@ -1660,7 +1660,7 @@ + resEl = 0;//(*this)[ colA] * (*right)[ rIx]; // initialization +- for( SizeT i=0; i < nColEl; ++i) ++ for( OMPInt i=0; i < nColEl; ++i) + resEl += (*this)[ i*nCol+colA] * (*right)[ rIx + i * nRow]; + } + } +@@ -1660,13 +1666,13 @@ #pragma omp parallel if (nOp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nOp)) default(shared) { #pragma omp for - for( int colA=0; colA < nCol; ++colA) // res dim 0 -+ for( SizeT colA=0; colA < nCol; ++colA) // res dim 0 - for( SizeT rIx=0, rowBnCol=0; rIx < rIxEnd; +- for( SizeT rIx=0, rowBnCol=0; rIx < rIxEnd; ++ for( OMPInt colA=0; colA < nCol; ++colA) // res dim 0 ++ for( OMPInt rIx=0, rowBnCol=0; rIx < rIxEnd; rIx += nColEl, ++rowBnCol) // res dim 1 { -@@ -1677,7 +1677,7 @@ + Ty& resEl = (*res)[ rowBnCol + colA * nRow]; + resEl = 0;//(*this)[ colA] * (*right)[ rIx]; // initialization +- for( SizeT i=0; i < nColEl; ++i) ++ for( OMPInt i=0; i < nColEl; ++i) + resEl += (*this)[ i*nCol+colA] * (*right)[ rIx+i]; + } + } +@@ -1677,12 +1683,12 @@ #pragma omp parallel if (nOp >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nOp)) default(shared) { #pragma omp for - for( int colA=0; colA < nCol; ++colA) // res dim 0 -+ for( SizeT colA=0; colA < nCol; ++colA) // res dim 0 - for( SizeT rIx=0; rIx < nRow; ++rIx) // res dim 1 +- for( SizeT rIx=0; rIx < nRow; ++rIx) // res dim 1 ++ for( OMPInt colA=0; colA < nCol; ++colA) // res dim 0 ++ for( OMPInt rIx=0; rIx < nRow; ++rIx) // res dim 1 { Ty& resEl = (*res)[ rIx + colA * nRow]; + resEl = 0;//(*this)[ colA] * (*right)[ rIx]; // initialization +- for( SizeT i=0; i < nColEl; ++i) ++ for( OMPInt i=0; i < nColEl; ++i) + resEl += (*this)[ i*nCol+colA] * (*right)[ rIx + i * nRow]; + } + } +@@ -1751,7 +1757,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = (*this)[i] & (*right)[i]; // & Ty(1); + } //C delete right; + return this; +@@ -1781,7 +1787,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*right)[i] == zero) (*this)[i]=zero; + // if( (*this)[i] == zero || (*right)[i] == zero) (*this)[i]=zero; + } //C delete right; +@@ -1805,7 +1811,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*this)[i] = (*right)[i]; + } //C delete right; + return this; +@@ -1829,7 +1835,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*right)[i] == zero) (*this)[i]=zero; + // if( (*this)[i] == zero || (*right)[i] == zero) (*this)[i]=zero; + } //C delete right; +@@ -1853,7 +1859,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*this)[i] = (*right)[i]; + } //C delete right; + return this; +@@ -1945,7 +1951,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared(s) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] &= s; + } + return this; +@@ -2008,7 +2014,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*this)[i] = s; + }} + return this; +@@ -2064,7 +2070,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*this)[i] = s; + }} + return this; +@@ -2147,7 +2153,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = (*this)[i] | (*right)[i]; // | Ty(1); + } + //C delete right; +@@ -2179,7 +2185,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] == zero) (*this)[i]=(*right)[i]; + } //C delete right; + return this; +@@ -2203,7 +2209,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*right)[i] != zero) (*this)[i] = (*right)[i]; + } //C delete right; + return this; +@@ -2228,7 +2234,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] == zero) (*this)[i]= (*right)[i]; + } //C delete right; + return this; +@@ -2252,7 +2258,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*right)[i] != zero) (*this)[i] = (*right)[i]; + } //C delete right; + return this; +@@ -2322,7 +2328,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = (*this)[i] | s; + } //C delete right; + return this; +@@ -2355,7 +2361,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] == zero) (*this)[i] = s; + }} //C delete right; + return this; +@@ -2395,7 +2401,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] == zero) (*this)[i] = s; + }} //C delete right; + return this; +@@ -2429,7 +2435,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*this)[i] = s; + }} //C delete right; + return this; +@@ -2505,7 +2511,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] ^= s; + }} + } +@@ -2515,7 +2521,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] ^= (*right)[i]; + } } + //C delete right; +@@ -2587,7 +2593,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] ^= s; + // (*this)[i] = (*this)[i] ^ s; + } //C delete right; +@@ -2645,1353 +2651,252 @@ + return this; + } + +-// Add +-// Adds right to itself, //C deletes right ++// LtMark ++// LtMarks right to itself, //C deletes right + // right must always have more or same number of elements + template +-BaseGDL* Data_::Add( BaseGDL* r) ++Data_* Data_::LtMark( BaseGDL* r) + { + Data_* right=static_cast(r); + +- // ULong rEl=right->N_Elements(); ++ // ULong rEl=right->N_Elements(); + ULong nEl=N_Elements(); +- // assert( rEl); ++ // assert( rEl); + assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); + if( nEl == 1) + { +- (*this)[0] += (*right)[0]; ++ if( (*this)[0] > (*right)[0]) (*this)[0]=(*right)[0]; + return this; + } +- + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] += (*right)[i]; ++ for( OMPInt i=0; i < nEl; ++i) ++ if( (*this)[i] > (*right)[i]) (*this)[i]=(*right)[i]; + } //C delete right; + return this; + } +-template +-BaseGDL* Data_::AddInv( BaseGDL* r) ++// invalid types ++DStructGDL* DStructGDL::LtMark( BaseGDL* r) + { +- assert( this->Type() != GDL_OBJ); // should never be called via this +- return Add( r); ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; + } + template<> +-BaseGDL* Data_::AddInv( BaseGDL* r) ++Data_* Data_::LtMark( BaseGDL* r) + { +- Data_* right=static_cast(r); +- +- // ULong rEl=right->N_Elements(); +- ULong nEl=N_Elements(); +- // assert( rEl); +- assert( nEl); +- if( nEl == 1) +- { +- (*this)[0] = (*right)[0] + (*this)[0]; +- return this; +- } +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] = (*right)[i] + (*this)[i]; +- } //C delete right; ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); + return this; + } +-// invalid types +-DStructGDL* DStructGDL::Add( BaseGDL* r) ++template<> ++Data_* Data_::LtMark( BaseGDL* r) + { +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); + return this; + } +-DStructGDL* DStructGDL::AddInv( BaseGDL* r) ++template<> ++Data_* Data_::LtMark( BaseGDL* r) + { +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); + return this; + } + template<> +-BaseGDL* Data_::Add( BaseGDL* r) ++Data_* Data_::LtMark( BaseGDL* r) + { + throw GDLException("Cannot apply operation to datatype PTR.",true,false); + return this; + } + template<> +-BaseGDL* Data_::Add( BaseGDL* r) +-{ +- // overload here +- Data_* self; +- DFun* plusOverload; +- +- ProgNodeP callingNode = interpreter->GetRetTree(); +- +- if( !Scalar()) +- { +- if( r->Type() == GDL_OBJ && r->Scalar()) +- { +- self = static_cast( r); +- plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOPlus)); +- if( plusOverload == NULL) +- { +- throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); +- } +- } +- else +- { +- throw GDLException( callingNode, "Cannot apply operation to non-scalar datatype OBJECT.", true, false); +- } +- } +- else +- { +- // Scalar() +- self = static_cast( this); +- plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOPlus)); +- if( plusOverload == NULL) +- { +- if( r->Type() == GDL_OBJ && r->Scalar()) +- { +- self = static_cast( r); +- plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOPlus)); +- if( plusOverload == NULL) +- { +- throw GDLException(callingNode,"Cannot apply not overloaded operator to datatype OBJECT.",true, false); +- } +- } +- else +- { +- throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); +- } +- } +- } +- +- assert( self->Scalar()); +- assert( plusOverload != NULL); +- +- // hidden SELF is counted as well +- int nParSub = plusOverload->NPar(); +- assert( nParSub >= 1); // SELF +- if( nParSub < 3) // (SELF), LEFT, RIGHT +- { +- throw GDLException( callingNode, plusOverload->ObjectName() + +- ": Incorrect number of arguments.", +- false, false); +- } +- EnvUDT* newEnv; +- Guard selfGuard; +- BaseGDL* thisP; +- // Dup() here is not optimal +- // avoid at least for internal overload routines (which do/must not change SELF or r) +- bool internalDSubUD = plusOverload->GetTree()->IsWrappedNode(); +- if( internalDSubUD) +- { +- thisP = this; +- newEnv= new EnvUDT( callingNode, plusOverload, &self); +- newEnv->SetNextParUnchecked( &thisP); // LEFT parameter, as reference to prevent cleanup in newEnv +- newEnv->SetNextParUnchecked( &r); // RVALUE parameter, as reference to prevent cleanup in newEnv +- } +- else +- { +- self = self->Dup(); +- selfGuard.Init( self); +- newEnv= new EnvUDT( callingNode, plusOverload, &self); +- newEnv->SetNextParUnchecked( this->Dup()); // LEFT parameter, as value +- newEnv->SetNextParUnchecked( r->Dup()); // RIGHT parameter, as value +- } +- +- +- // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack +- StackGuard guard(interpreter->CallStack()); +- +- interpreter->CallStack().push_back( newEnv); +- +- // make the call +- BaseGDL* res=interpreter->call_fun(static_cast(newEnv->GetPro())->GetTree()); +- +- if( !internalDSubUD && self != selfGuard.Get()) +- { +- // always put out warning first, in case of a later crash +- Warning( "WARNING: " + plusOverload->ObjectName() + +- ": Assignment to SELF detected (GDL session still ok)."); +- // assignment to SELF -> self was deleted and points to new variable +- // which it owns +- selfGuard.Release(); +- if( static_cast(self) != NullGDL::GetSingleInstance()) +- selfGuard.Reset(self); +- } +- return res; +-} +-// difference from above: Order of parameters in call +-template<> +-BaseGDL* Data_::AddInv( BaseGDL* r) ++Data_* Data_::LtMark( BaseGDL* r) + { +- if( r->Type() == GDL_OBJ && r->Scalar()) +- { +- return r->Add( this); // for right order of parameters +- } +- +- // overload here +- Data_* self; +- DFun* plusOverload; +- +- ProgNodeP callingNode = interpreter->GetRetTree(); +- +- if( !Scalar()) +- { +- throw GDLException( callingNode, "Cannot apply operation to non-scalar datatype OBJECT.", true, false); +- } +- else +- { +- // Scalar() +- self = static_cast( this); +- plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOPlus)); +- if( plusOverload == NULL) +- { +- throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); +- } +- } +- +- assert( self->Scalar()); +- assert( plusOverload != NULL); +- +- // hidden SELF is counted as well +- int nParSub = plusOverload->NPar(); +- assert( nParSub >= 1); // SELF +- if( nParSub < 3) // (SELF), LEFT, RIGHT +- { +- throw GDLException( callingNode, plusOverload->ObjectName() + +- ": Incorrect number of arguments.", +- false, false); +- } +- EnvUDT* newEnv; +- Guard selfGuard; +- BaseGDL* thisP; +- // Dup() here is not optimal +- // avoid at least for internal overload routines (which do/must not change SELF or r) +- bool internalDSubUD = plusOverload->GetTree()->IsWrappedNode(); +- if( internalDSubUD) +- { +- thisP = this; +- newEnv= new EnvUDT( callingNode, plusOverload, &self); +- // order different to Add +- newEnv->SetNextParUnchecked( &r); // RVALUE parameter, as reference to prevent cleanup in newEnv +- newEnv->SetNextParUnchecked( &thisP); // LEFT parameter, as reference to prevent cleanup in newEnv +- } +- else +- { +- self = self->Dup(); +- selfGuard.Init( self); +- newEnv= new EnvUDT( callingNode, plusOverload, &self); +- // order different to Add +- newEnv->SetNextParUnchecked( r->Dup()); // RIGHT parameter, as value +- newEnv->SetNextParUnchecked( this->Dup()); // LEFT parameter, as value +- } +- +- +- // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack +- StackGuard guard(interpreter->CallStack()); +- +- interpreter->CallStack().push_back( newEnv); +- +- // make the call +- BaseGDL* res=interpreter->call_fun(static_cast(newEnv->GetPro())->GetTree()); +- +- if( !internalDSubUD && self != selfGuard.Get()) +- { +- // always put out warning first, in case of a later crash +- Warning( "WARNING: " + plusOverload->ObjectName() + +- ": Assignment to SELF detected (GDL session still ok)."); +- // assignment to SELF -> self was deleted and points to new variable +- // which it owns +- selfGuard.Release(); +- if( static_cast(self) != NullGDL::GetSingleInstance()) +- selfGuard.Reset(self); +- } +- return res; ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; + } +- + template +-BaseGDL* Data_::AddS( BaseGDL* r) ++Data_* Data_::LtMarkS( BaseGDL* r) + { + Data_* right=static_cast(r); +- ++ + ULong nEl=N_Elements(); + assert( nEl); +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); + if( nEl == 1) + { +- (*this)[0] += (*right)[0]; ++ if( (*this)[0] > (*right)[0]) (*this)[0]=(*right)[0]; + return this; + } + Ty s = (*right)[0]; + // right->Scalar(s); +- // dd += s; + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] += s; ++ for( OMPInt i=0; i < nEl; ++i) ++ if( (*this)[i] > s) (*this)[i]=s; + } //C delete right; + return this; + } +-template +-BaseGDL* Data_::AddInvS( BaseGDL* r) ++// invalid types ++DStructGDL* DStructGDL::LtMarkS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::LtMarkS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::LtMarkS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); ++ return this; ++} ++template<> ++Data_* Data_::LtMarkS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); ++ return this; ++} ++template<> ++Data_* Data_::LtMarkS( BaseGDL* r) + { +- return AddS( r); ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; + } + template<> +-BaseGDL* Data_::AddInvS( BaseGDL* r) ++Data_* Data_::LtMarkS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++// GtMark ++// GtMarks right to itself, //C deletes right ++// right must always have more or same number of elements ++template ++Data_* Data_::GtMark( BaseGDL* r) + { + Data_* right=static_cast(r); + ++ // ULong rEl=right->N_Elements(); + ULong nEl=N_Elements(); ++ // assert( rEl); + assert( nEl); + // if( !rEl || !nEl) throw GDLException("Variable is undefined."); + if( nEl == 1) + { +- (*this)[0] = (*right)[0] + (*this)[0] ; ++ if( (*this)[0] < (*right)[0]) (*this)[0]=(*right)[0]; + return this; + } +- Ty s = (*right)[0]; +- // right->Scalar(s); + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] = s + (*this)[i]; ++ for( OMPInt i=0; i < nEl; ++i) ++ if( (*this)[i] < (*right)[i]) (*this)[i]=(*right)[i]; + } //C delete right; + return this; + } +- + // invalid types +-DStructGDL* DStructGDL::AddS( BaseGDL* r) ++DStructGDL* DStructGDL::GtMark( BaseGDL* r) + { + throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); + return this; + } +-DStructGDL* DStructGDL::AddInvS( BaseGDL* r) ++template<> ++Data_* Data_::GtMark( BaseGDL* r) + { +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); + return this; + } + template<> +-BaseGDL* Data_::AddS( BaseGDL* r) ++Data_* Data_::GtMark( BaseGDL* r) + { +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); + return this; + } + template<> +-BaseGDL* Data_::AddS( BaseGDL* r) ++Data_* Data_::GtMark( BaseGDL* r) + { +- return Add( r); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); ++ return this; + } + template<> +-BaseGDL* Data_::AddInvS( BaseGDL* r) ++Data_* Data_::GtMark( BaseGDL* r) + { +- return AddInv( r); ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; + } +- +-// Sub +-// substraction: left=left-right +-template +-BaseGDL* Data_::Sub( BaseGDL* r) ++template<> ++Data_* Data_::GtMark( BaseGDL* r) + { +- Data_* right=static_cast(r); +- +- ULong rEl=right->N_Elements(); +- ULong nEl=N_Elements(); +- assert( rEl); +- assert( nEl); +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- if( nEl == rEl) +- dd -= right->dd; +- else +- { +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] -= (*right)[i]; +- }} //C delete right; ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); + return this; + } +-// inverse substraction: left=right-left + template +-BaseGDL* Data_::SubInv( BaseGDL* r) ++Data_* Data_::GtMarkS( BaseGDL* r) + { + Data_* right=static_cast(r); + +- ULong rEl=right->N_Elements(); + ULong nEl=N_Elements(); +- assert( rEl); + assert( nEl); +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- /* if( nEl == rEl) +- dd = right->dd - dd; +- else*/ + if( nEl == 1) + { +- (*this)[0] = (*right)[0] - (*this)[0]; ++ if( (*this)[0] < (*right)[0]) (*this)[0]=(*right)[0]; + return this; + } ++ ++ Ty s = (*right)[0]; ++ // right->Scalar(s); + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] = (*right)[i] - (*this)[i]; ++ for( OMPInt i=0; i < nEl; ++i) ++ if( (*this)[i] < s) (*this)[i]=s; + } //C delete right; + return this; + } + // invalid types +-DStructGDL* DStructGDL::Sub( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-DStructGDL* DStructGDL::SubInv( BaseGDL* r) ++DStructGDL* DStructGDL::GtMarkS( BaseGDL* r) + { + throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); + return this; + } + template<> +-BaseGDL* Data_::Sub( BaseGDL* r) ++Data_* Data_::GtMarkS( BaseGDL* r) + { + throw GDLException("Cannot apply operation to datatype STRING.",true,false); + return this; + } + template<> +-BaseGDL* Data_::SubInv( BaseGDL* r) ++Data_* Data_::GtMarkS( BaseGDL* r) + { +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); + return this; + } + template<> +-BaseGDL* Data_::Sub( BaseGDL* r) ++Data_* Data_::GtMarkS( BaseGDL* r) + { +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ throw GDLException("Cannot apply operation to datatype "+str+".",true,false); + return this; + } + template<> +-BaseGDL* Data_::SubInv( BaseGDL* r) ++Data_* Data_::GtMarkS( BaseGDL* r) + { + throw GDLException("Cannot apply operation to datatype PTR.",true,false); + return this; + } + template<> +-BaseGDL* Data_::Sub( BaseGDL* r) ++Data_* Data_::GtMarkS( BaseGDL* r) + { +- // overload here +- Data_* self; +- DFun* plusOverload; +- +- ProgNodeP callingNode = interpreter->GetRetTree(); ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} + +- if( !Scalar()) +- { +- if( r->Type() == GDL_OBJ && r->Scalar()) +- { +- self = static_cast( r); +- plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOMinus)); +- if( plusOverload == NULL) +- { +- throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); +- } +- } +- else +- { +- throw GDLException( callingNode, "Cannot apply operation to non-scalar datatype OBJECT.", true, false); +- } +- } +- else +- { +- // Scalar() +- self = static_cast( this); +- plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOMinus)); +- if( plusOverload == NULL) +- { +- if( r->Type() == GDL_OBJ && r->Scalar()) +- { +- self = static_cast( r); +- plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOMinus)); +- if( plusOverload == NULL) +- { +- throw GDLException(callingNode,"Cannot apply not overloaded operator to datatype OBJECT.",true, false); +- } +- } +- else +- { +- throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); +- } +- } +- } +- +- assert( self->Scalar()); +- assert( plusOverload != NULL); +- +- // hidden SELF is counted as well +- int nParSub = plusOverload->NPar(); +- assert( nParSub >= 1); // SELF +- if( nParSub < 3) // (SELF), LEFT, RIGHT +- { +- throw GDLException( callingNode, plusOverload->ObjectName() + +- ": Incorrect number of arguments.", +- false, false); +- } +- EnvUDT* newEnv; +- Guard selfGuard; +- BaseGDL* thisP; +- // Dup() here is not optimal +- // avoid at least for internal overload routines (which do/must not change SELF or r) +- bool internalDSubUD = plusOverload->GetTree()->IsWrappedNode(); +- if( internalDSubUD) +- { +- thisP = this; +- newEnv= new EnvUDT( callingNode, plusOverload, &self); +- newEnv->SetNextParUnchecked( &thisP); // LEFT parameter, as reference to prevent cleanup in newEnv +- newEnv->SetNextParUnchecked( &r); // RVALUE parameter, as reference to prevent cleanup in newEnv +- } +- else +- { +- self = self->Dup(); +- selfGuard.Init( self); +- newEnv= new EnvUDT( callingNode, plusOverload, &self); +- newEnv->SetNextParUnchecked( this->Dup()); // LEFT parameter, as value +- newEnv->SetNextParUnchecked( r->Dup()); // RIGHT parameter, as value +- } +- +- +- // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack +- StackGuard guard(interpreter->CallStack()); +- +- interpreter->CallStack().push_back( newEnv); +- +- // make the call +- BaseGDL* res=interpreter->call_fun(static_cast(newEnv->GetPro())->GetTree()); +- +- if( !internalDSubUD && self != selfGuard.Get()) +- { +- // always put out warning first, in case of a later crash +- Warning( "WARNING: " + plusOverload->ObjectName() + +- ": Assignment to SELF detected (GDL session still ok)."); +- // assignment to SELF -> self was deleted and points to new variable +- // which it owns +- selfGuard.Release(); +- if( static_cast(self) != NullGDL::GetSingleInstance()) +- selfGuard.Reset(self); +- } +- return res; +-} +-template<> +-BaseGDL* Data_::SubInv( BaseGDL* r) +-{ +- if( r->Type() == GDL_OBJ && r->Scalar()) +- { +- return r->Sub( this); // for right order of parameters +- } +- +- // overload here +- Data_* self; +- DFun* plusOverload; +- +- ProgNodeP callingNode = interpreter->GetRetTree(); +- +- if( !Scalar()) +- { +- throw GDLException( callingNode, "Cannot apply operation to non-scalar datatype OBJECT.", true, false); +- } +- else +- { +- // Scalar() +- self = static_cast( this); +- plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOMinus)); +- if( plusOverload == NULL) +- { +- throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); +- } +- } +- +- assert( self->Scalar()); +- assert( plusOverload != NULL); +- +- // hidden SELF is counted as well +- int nParSub = plusOverload->NPar(); +- assert( nParSub >= 1); // SELF +- if( nParSub < 3) // (SELF), LEFT, RIGHT +- { +- throw GDLException( callingNode, plusOverload->ObjectName() + +- ": Incorrect number of arguments.", +- false, false); +- } +- EnvUDT* newEnv; +- Guard selfGuard; +- BaseGDL* thisP; +- // Dup() here is not optimal +- // avoid at least for internal overload routines (which do/must not change SELF or r) +- bool internalDSubUD = plusOverload->GetTree()->IsWrappedNode(); +- if( internalDSubUD) +- { +- thisP = this; +- newEnv= new EnvUDT( callingNode, plusOverload, &self); +- // order different to Add +- newEnv->SetNextParUnchecked( &r); // RVALUE parameter, as reference to prevent cleanup in newEnv +- newEnv->SetNextParUnchecked( &thisP); // LEFT parameter, as reference to prevent cleanup in newEnv +- } +- else +- { +- self = self->Dup(); +- selfGuard.Init( self); +- newEnv= new EnvUDT( callingNode, plusOverload, &self); +- // order different to Add +- newEnv->SetNextParUnchecked( r->Dup()); // RIGHT parameter, as value +- newEnv->SetNextParUnchecked( this->Dup()); // LEFT parameter, as value +- } +- +- +- // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack +- StackGuard guard(interpreter->CallStack()); +- +- interpreter->CallStack().push_back( newEnv); +- +- // make the call +- BaseGDL* res=interpreter->call_fun(static_cast(newEnv->GetPro())->GetTree()); +- +- if( !internalDSubUD && self != selfGuard.Get()) +- { +- // always put out warning first, in case of a later crash +- Warning( "WARNING: " + plusOverload->ObjectName() + +- ": Assignment to SELF detected (GDL session still ok)."); +- // assignment to SELF -> self was deleted and points to new variable +- // which it owns +- selfGuard.Release(); +- if( static_cast(self) != NullGDL::GetSingleInstance()) +- selfGuard.Reset(self); +- } +- return res; +-} +-template +-Data_* Data_::SubS( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- ULong nEl=N_Elements(); +- assert( nEl); +- if( nEl == 1) +- { +- (*this)[0] -= (*right)[0]; +- return this; +- } +- +- Ty s = (*right)[0]; +- // right->Scalar(s); +- // dd -= s; +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] -= s; +- } //C delete right; +- return this; +-} +-// inverse substraction: left=right-left +-template +-Data_* Data_::SubInvS( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- ULong nEl=N_Elements(); +- assert( nEl); +- +- if( nEl == 1) +- { +- (*this)[0] = (*right)[0] - (*this)[0]; +- return this; +- } +- +- Ty s = (*right)[0]; +- // right->Scalar(s); +- // dd = s - dd; +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] = s - (*this)[i]; +- } //C delete right; +- return this; +-} +-// invalid types +-DStructGDL* DStructGDL::SubS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-DStructGDL* DStructGDL::SubInvS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::SubS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::SubInvS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::SubS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::SubInvS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::SubS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::SubInvS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +- +-// LtMark +-// LtMarks right to itself, //C deletes right +-// right must always have more or same number of elements +-template +-Data_* Data_::LtMark( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- // ULong rEl=right->N_Elements(); +- ULong nEl=N_Elements(); +- // assert( rEl); +- assert( nEl); +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- if( nEl == 1) +- { +- if( (*this)[0] > (*right)[0]) (*this)[0]=(*right)[0]; +- return this; +- } +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- if( (*this)[i] > (*right)[i]) (*this)[i]=(*right)[i]; +- } //C delete right; +- return this; +-} +-// invalid types +-DStructGDL* DStructGDL::LtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype "+str+".",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype "+str+".",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +-template +-Data_* Data_::LtMarkS( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- ULong nEl=N_Elements(); +- assert( nEl); +- if( nEl == 1) +- { +- if( (*this)[0] > (*right)[0]) (*this)[0]=(*right)[0]; +- return this; +- } +- Ty s = (*right)[0]; +- // right->Scalar(s); +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- if( (*this)[i] > s) (*this)[i]=s; +- } //C delete right; +- return this; +-} +-// invalid types +-DStructGDL* DStructGDL::LtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype "+str+".",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype "+str+".",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::LtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +-// GtMark +-// GtMarks right to itself, //C deletes right +-// right must always have more or same number of elements +-template +-Data_* Data_::GtMark( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- // ULong rEl=right->N_Elements(); +- ULong nEl=N_Elements(); +- // assert( rEl); +- assert( nEl); +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- if( nEl == 1) +- { +- if( (*this)[0] < (*right)[0]) (*this)[0]=(*right)[0]; +- return this; +- } +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- if( (*this)[i] < (*right)[i]) (*this)[i]=(*right)[i]; +- } //C delete right; +- return this; +-} +-// invalid types +-DStructGDL* DStructGDL::GtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype "+str+".",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype "+str+".",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMark( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +-template +-Data_* Data_::GtMarkS( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- ULong nEl=N_Elements(); +- assert( nEl); +- if( nEl == 1) +- { +- if( (*this)[0] < (*right)[0]) (*this)[0]=(*right)[0]; +- return this; +- } +- +- Ty s = (*right)[0]; +- // right->Scalar(s); +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- if( (*this)[i] < s) (*this)[i]=s; +- } //C delete right; +- return this; +-} +-// invalid types +-DStructGDL* DStructGDL::GtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype "+str+".",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype "+str+".",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::GtMarkS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +- +-// Mult +-// Mults right to itself, //C deletes right +-// right must always have more or same number of elements +-template +-Data_* Data_::Mult( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- // ULong rEl=right->N_Elements(); +- ULong nEl=N_Elements(); +- // assert( rEl); +- assert( nEl); +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- if( nEl == 1) +- { +- (*this)[0] *= (*right)[0]; +- return this; +- } +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] *= (*right)[i]; +- } //C delete right; +- return this; +-} +-// invalid types +-DStructGDL* DStructGDL::Mult( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::Mult( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::Mult( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::Mult( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +- +-template +-Data_* Data_::MultS( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- ULong nEl=N_Elements(); +- assert( nEl); +- if( nEl == 1) +- { +- (*this)[0] *= (*right)[0]; +- return this; +- } +- Ty s = (*right)[0]; +- // right->Scalar(s); +- // dd *= s; +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +-#pragma omp for +- for( int i=0; i < nEl; ++i) +- (*this)[i] *= s; +- } //C delete right; +- return this; +-} +-// invalid types +-DStructGDL* DStructGDL::MultS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::MultS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::MultS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::MultS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +- +-// Div +-// division: left=left/right +-template +-Data_* Data_::Div( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- // ULong rEl=right->N_Elements(); +- ULong nEl=N_Elements(); +- // assert( rEl); +- assert( nEl); +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- +- SizeT i = 0; +- +- if( sigsetjmp( sigFPEJmpBuf, 1) == 0) +- { +- // TODO: Check if we can use OpenMP here (is longjmp allowed?) +- // if yes: need to run the full loop after the longjmp +- for( /*SizeT i=0*/; i < nEl; ++i) +- (*this)[i] /= (*right)[i]; +- //C delete right; +- return this; +- } +- else +- { +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- // bool zeroEncountered = false; // until zero operation is already done. +-#pragma omp for +- for( int ix=i; ix < nEl; ++ix) +- /* if( !zeroEncountered) +- { +- if( (*right)[ix] == this->zero) +- zeroEncountered = true; +- } +- else*/ +- if( (*right)[ix] != this->zero) (*this)[ix] /= (*right)[ix]; +- } //C delete right; +- return this; +- } +-} +-// inverse division: left=right/left +-template +-Data_* Data_::DivInv( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- // ULong rEl=right->N_Elements(); +- ULong nEl=N_Elements(); +- // assert( rEl); +- assert( nEl); +- +- SizeT i = 0; +- +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- if( sigsetjmp( sigFPEJmpBuf, 1) == 0) +- { +- for( /*SizeT i=0*/; i < nEl; ++i) +- (*this)[i] = (*right)[i] / (*this)[i]; +- //C delete right; +- return this; +- } +- else +- { +- TRACEOMP( __FILE__, __LINE__) +-#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- // bool zeroEncountered = false; // until zero operation is already done. +-#pragma omp for +- for( int ix=i; ix < nEl; ++ix) +- /* if( !zeroEncountered) +- { +- if( (*this)[ix] == this->zero) +- { +- zeroEncountered = true; +- (*this)[ ix] = (*right)[i]; +- } +- } +- else*/ +- if( (*this)[ix] != this->zero) +- (*this)[ix] = (*right)[ix] / (*this)[ix]; +- else +- (*this)[ix] = (*right)[ix]; +- } //C delete right; +- return this; +- } +-} +-// invalid types +-DStructGDL* DStructGDL::Div( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-DStructGDL* DStructGDL::DivInv( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::Div( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivInv( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::Div( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivInv( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::Div( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivInv( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +-template +-Data_* Data_::DivS( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- ULong nEl=N_Elements(); +- assert( nEl); +- Ty s = (*right)[0]; +- +- // remember: this is a template (must work for several types) +- // due to error handling the actual devision by 0 +- // has to be done +- // but if not 0, we save the expensive error handling +- if( s != this->zero) +- { +- for(SizeT i=0; i < nEl; ++i) +- { +- (*this)[i] /= s; +- } +- return this; +- } +- if( sigsetjmp( sigFPEJmpBuf, 1) == 0) +- { +- for(SizeT i=0; i < nEl; ++i) +- { +- (*this)[i] /= s; +- } +- return this; +- } +- return this; +-} +- +-// inverse division: left=right/left +-template +-Data_* Data_::DivInvS( BaseGDL* r) +-{ +- Data_* right=static_cast(r); +- +- ULong nEl=N_Elements(); +- assert( nEl); +- // if( !rEl || !nEl) throw GDLException("Variable is undefined."); +- +- // remember: this is a template (must work for several types) +- // due to error handling the actual devision by 0 +- // has to be done +- // but if not 0, we save the expensive error handling +- if( nEl == 1 && (*this)[0] != this->zero) +- { +- (*this)[0] = (*right)[0] / (*this)[0]; +- return this; +- } +- +- Ty s = (*right)[0]; +- SizeT i=0; +- if( sigsetjmp( sigFPEJmpBuf, 1) == 0) +- { +- // right->Scalar(s); +- for( /*SizeT i=0*/; i < nEl; ++i) +- (*this)[i] = s / (*this)[i]; +- //C delete right; +- return this; +- } +- else +- { +-// TRACEOMP( __FILE__, __LINE__) +-// #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +-// { +-// // bool zeroEncountered = false; +-// #pragma omp for +- // right->Scalar(s); +- for( SizeT ix=i; ix < nEl; ++ix) +- /* if( !zeroEncountered) +- { +- if( (*this)[ix] == this->zero) +- { +- zeroEncountered = true; +- (*this)[ix] = s; +- } +- } +- else*/ +- if( (*this)[ix] != this->zero) +- (*this)[ix] = s / (*this)[ix]; +- else +- (*this)[ix] = s; +-// } //C delete right; +- return this; +- } +-} +-// invalid types +-DStructGDL* DStructGDL::DivS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-DStructGDL* DStructGDL::DivInvS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivInvS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype STRING.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivInvS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype PTR.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} +-template<> +-Data_* Data_::DivInvS( BaseGDL* r) +-{ +- throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); +- return this; +-} + + // Mod + // modulo division: left=left % right +@@ -4021,7 +2926,7 @@ + { + // bool zeroEncountered = false; + #pragma omp for +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + /* if( !zeroEncountered) + { + if( (*right)[i] == this->zero) +@@ -4066,7 +2971,7 @@ + { + // bool zeroEncountered = false; + #pragma omp for +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + /* if( !zeroEncountered) + { + if( (*this)[ix] == this->zero) +@@ -4105,7 +3010,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = Modulo((*this)[i],(*right)[i]); + } //C delete right; + return this; +@@ -4125,7 +3030,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = Modulo((*right)[i],(*this)[i]); + } //C delete right; + return this; +@@ -4152,7 +3057,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = DModulo((*this)[i],(*right)[i]); + } //C delete right; + return this; +@@ -4172,7 +3077,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = DModulo((*right)[i],(*this)[i]); + } //C delete right; + return this; +@@ -4336,7 +3241,7 @@ + #pragma omp for + // bool zeroEncountered = false; + // right->Scalar(s); +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + /* if( !zeroEncountered) + { + if( (*this)[ix] == this->zero) +@@ -4368,7 +3273,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = Modulo((*this)[i],s); + } //C delete right; + return this; +@@ -4388,7 +3293,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = Modulo(s,(*this)[i]); + } //C delete right; + return this; +@@ -4406,7 +3311,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = DModulo((*this)[i],s); + } //C delete right; + return this; +@@ -4425,7 +3330,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = DModulo(s,(*this)[i]); + } //C delete right; + return this; +@@ -4545,7 +3450,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], (*right)[i]); // valarray + } //C delete right; + return this; +@@ -4568,7 +3473,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*right)[i], (*this)[i]); + } //C delete right; + return this; +@@ -4594,7 +3499,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], (*right)[i]); + } } + return this; +@@ -4629,7 +3534,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], r0); + } return this; + } +@@ -4641,7 +3546,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[ i] = pow( s0, (*right)[ i]); + } return res; + } +@@ -4651,7 +3556,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], (*right)[i]); + } return this; + } +@@ -4662,7 +3567,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } return res; + } +@@ -4684,7 +3589,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], r0); + } return this; + } +@@ -4696,7 +3601,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[ i] = pow( s0, (*right)[ i]); + } return res; + } +@@ -4706,7 +3611,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], (*right)[i]); + } return this; + } +@@ -4717,7 +3622,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } return res; + } +@@ -4742,7 +3647,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*right)[i], (*this)[i]); + } //C delete right; + return this; +@@ -4767,7 +3672,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], (*right)[i]); + } //C delete right; + return this; +@@ -4792,7 +3697,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*right)[i], (*this)[i]); + } //C delete right; + return this; +@@ -4821,7 +3726,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], (*right)[i]); + } + #endif +@@ -4986,7 +3891,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*right)[i], (*this)[i]); + #endif + } //C delete right; +@@ -5016,7 +3921,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], (*right)[i]); + } + #endif +@@ -5183,7 +4088,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*right)[i], (*this)[i]); + } + #endif +@@ -5252,7 +4157,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( (*this)[i], s); + } + //C delete right; +@@ -5274,7 +4179,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*this)[i] = pow( s, (*this)[i]); + } //C delete right; + return this; +@@ -5293,7 +4198,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i ++// #include "sigfpehandler.hpp" ++// ++// #ifdef _OPENMP ++// #include ++// #endif ++// ++// #include "typetraits.hpp" ++// ++// using namespace std; ++ ++// Div ++// division: left=left/right ++template ++Data_* Data_::Div( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ // ULong rEl=right->N_Elements(); ++ ULong nEl=N_Elements(); ++ // assert( rEl); ++ assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ ++ SizeT i = 0; ++ ++ if( sigsetjmp( sigFPEJmpBuf, 1) == 0) ++ { ++ // TODO: Check if we can use OpenMP here (is longjmp allowed?) ++ // if yes: need to run the full loop after the longjmp ++ for( /*SizeT i=0*/; i < nEl; ++i) ++ (*this)[i] /= (*right)[i]; ++ //C delete right; ++ return this; ++ } ++ else ++ { ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++ // bool zeroEncountered = false; // until zero operation is already done. ++#pragma omp for ++ for( OMPInt ix=i; ix < nEl; ++ix) ++ /* if( !zeroEncountered) ++ { ++ if( (*right)[ix] == this->zero) ++ zeroEncountered = true; ++ } ++ else*/ ++ if( (*right)[ix] != this->zero) (*this)[ix] /= (*right)[ix]; ++ } //C delete right; ++ return this; ++ } ++} ++// inverse division: left=right/left ++template ++Data_* Data_::DivInv( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ // ULong rEl=right->N_Elements(); ++ ULong nEl=N_Elements(); ++ // assert( rEl); ++ assert( nEl); ++ ++ SizeT i = 0; ++ ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ if( sigsetjmp( sigFPEJmpBuf, 1) == 0) ++ { ++ for( /*SizeT i=0*/; i < nEl; ++i) ++ (*this)[i] = (*right)[i] / (*this)[i]; ++ //C delete right; ++ return this; ++ } ++ else ++ { ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++ // bool zeroEncountered = false; // until zero operation is already done. ++#pragma omp for ++ for( OMPInt ix=i; ix < nEl; ++ix) ++ /* if( !zeroEncountered) ++ { ++ if( (*this)[ix] == this->zero) ++ { ++ zeroEncountered = true; ++ (*this)[ ix] = (*right)[i]; ++ } ++ } ++ else*/ ++ if( (*this)[ix] != this->zero) ++ (*this)[ix] = (*right)[ix] / (*this)[ix]; ++ else ++ (*this)[ix] = (*right)[ix]; ++ } //C delete right; ++ return this; ++ } ++} ++// invalid types ++DStructGDL* DStructGDL::Div( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++DStructGDL* DStructGDL::DivInv( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::Div( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivInv( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::Div( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivInv( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::Div( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivInv( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++template ++Data_* Data_::DivS( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong nEl=N_Elements(); ++ assert( nEl); ++ Ty s = (*right)[0]; ++ ++ // remember: this is a template (must work for several types) ++ // due to error handling the actual devision by 0 ++ // has to be done ++ // but if not 0, we save the expensive error handling ++ if( s != this->zero) ++ { ++ for(SizeT i=0; i < nEl; ++i) ++ { ++ (*this)[i] /= s; ++ } ++ return this; ++ } ++ if( sigsetjmp( sigFPEJmpBuf, 1) == 0) ++ { ++ for(SizeT i=0; i < nEl; ++i) ++ { ++ (*this)[i] /= s; ++ } ++ return this; ++ } ++ return this; ++} ++ ++// inverse division: left=right/left ++template ++Data_* Data_::DivInvS( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong nEl=N_Elements(); ++ assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ ++ // remember: this is a template (must work for several types) ++ // due to error handling the actual devision by 0 ++ // has to be done ++ // but if not 0, we save the expensive error handling ++ if( nEl == 1 && (*this)[0] != this->zero) ++ { ++ (*this)[0] = (*right)[0] / (*this)[0]; ++ return this; ++ } ++ ++ Ty s = (*right)[0]; ++ SizeT i=0; ++ if( sigsetjmp( sigFPEJmpBuf, 1) == 0) ++ { ++ // right->Scalar(s); ++ for( /*SizeT i=0*/; i < nEl; ++i) ++ (*this)[i] = s / (*this)[i]; ++ //C delete right; ++ return this; ++ } ++ else ++ { ++// TRACEOMP( __FILE__, __LINE__) ++// #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// // bool zeroEncountered = false; ++// #pragma omp for ++ // right->Scalar(s); ++ for( SizeT ix=i; ix < nEl; ++ix) ++ /* if( !zeroEncountered) ++ { ++ if( (*this)[ix] == this->zero) ++ { ++ zeroEncountered = true; ++ (*this)[ix] = s; ++ } ++ } ++ else*/ ++ if( (*this)[ix] != this->zero) ++ (*this)[ix] = s / (*this)[ix]; ++ else ++ (*this)[ix] = s; ++// } //C delete right; ++ return this; ++ } ++} ++// invalid types ++DStructGDL* DStructGDL::DivS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++DStructGDL* DStructGDL::DivInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::DivInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++ ++ ++ ++#endif +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_op_mult.cpp gdl/src/basic_op_mult.cpp +--- gdl-0.9.3/src/basic_op_mult.cpp 1969-12-31 17:00:00.000000000 -0700 ++++ gdl/src/basic_op_mult.cpp 2013-03-12 05:11:52.000000000 -0600 +@@ -0,0 +1,156 @@ ++/*************************************************************************** ++ basic_op_mult.cpp - GDL mult (*) operators ++ ------------------- ++ begin : July 22 2002 ++ copyright : (C) 2002 by Marc Schellens ++ email : m_schellens@users.sf.net ++***************************************************************************/ ++ ++/*************************************************************************** ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ ***************************************************************************/ ++ ++// to be included from datatypes.cpp ++#ifdef INCLUDE_BASIC_OP_CPP ++ ++// // header in datatypes.hpp ++// ++// //#include "datatypes.hpp" ++// //#include "dstructgdl.hpp" ++// //#include "arrayindex.hpp" ++// ++// //#include ++// #include "sigfpehandler.hpp" ++// ++// #ifdef _OPENMP ++// #include ++// #endif ++// ++// #include "typetraits.hpp" ++// ++// using namespace std; ++ ++// Mult ++// Mults right to itself, //C deletes right ++// right must always have more or same number of elements ++template ++Data_* Data_::Mult( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ // ULong rEl=right->N_Elements(); ++ ULong nEl=N_Elements(); ++ // assert( rEl); ++ assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ if( nEl == 1) ++ { ++ (*this)[0] *= (*right)[0]; ++ return this; ++ } ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRight(&(*right)[0], nEl); ++ mThis *= mRight; ++ return this; ++#else ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] *= (*right)[i]; ++ } //C delete right; ++ return this; ++#endif ++ ++} ++// invalid types ++DStructGDL* DStructGDL::Mult( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::Mult( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::Mult( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::Mult( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++ ++template ++Data_* Data_::MultS( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong nEl=N_Elements(); ++ assert( nEl); ++ if( nEl == 1) ++ { ++ (*this)[0] *= (*right)[0]; ++ return this; ++ } ++ Ty s = (*right)[0]; ++ // right->Scalar(s); ++ // dd *= s; ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ mThis *= s; ++ return this; ++#else ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] *= s; ++ } //C delete right; ++ return this; ++#endif ++ ++} ++// invalid types ++DStructGDL* DStructGDL::MultS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::MultS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::MultS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::MultS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++ ++#endif +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_op_new.cpp gdl/src/basic_op_new.cpp +--- gdl-0.9.3/src/basic_op_new.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/basic_op_new.cpp 2013-03-21 14:04:04.272825662 -0600 +@@ -54,7 +54,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] & (*right)[i]; // & Ty(1); + } + return res; +@@ -86,7 +86,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for ( int i=0; i < nEl; ++i ) ++ for ( OMPInt i=0; i < nEl; ++i ) + if ( (*right)[i] == zero ) (*res)[i] = zero; else (*res)[i] = (*this)[i]; + } + return res; +@@ -110,7 +110,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*res)[i] = (*right)[i]; else (*res)[i] = zero; + } + return res; +@@ -135,7 +135,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if ( (*right)[i] == zero ) (*res)[i] = zero; else (*res)[i] = (*this)[i]; + } + return res; +@@ -159,7 +159,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*res)[i] = (*right)[i]; else (*res)[i] = zero; + } + return res; +@@ -245,7 +245,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared(s) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] & s; + } + return res; +@@ -291,7 +291,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*res)[i] = s; else (*res)[i] = zero; + } + return res; +@@ -332,7 +332,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*res)[i] = s; else (*res)[i] = zero; + } + return res; +@@ -418,7 +418,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] | (*right)[i]; // | Ty(1); + } + //C delete right; +@@ -451,7 +451,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] == zero) (*res)[i] = (*right)[i]; else (*res)[i] = (*this)[i]; + } //C delete right; + return res; +@@ -475,7 +475,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*right)[i] != zero) (*res)[i] = (*right)[i]; else (*res)[i] = (*this)[i]; + } //C delete right; + return res; +@@ -501,7 +501,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] == zero) (*res)[i] = (*right)[i]; else (*res)[i] = (*this)[i]; + } //C delete right; + return res; +@@ -525,7 +525,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*right)[i] != zero) (*res)[i] = (*right)[i]; else (*res)[i] = (*this)[i]; + } //C delete right; + return res; +@@ -595,7 +595,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] | s; + } //C delete right; + return res; +@@ -628,7 +628,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] == zero) (*res)[i] = s; else (*res)[i] = (*this)[i]; + } + return res; +@@ -664,7 +664,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*res)[i] = s; else (*res)[i] = zero; + } + return res; +@@ -691,7 +691,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] == zero) (*res)[i] = s; else (*res)[i] = (*this)[i]; + } + return res; +@@ -725,7 +725,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] != zero) (*res)[i] = s; else (*res)[i] = zero; + } + return res; +@@ -805,7 +805,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] ^ s; + } + return res; +@@ -817,7 +817,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] ^ (*right)[i]; + } + return res; +@@ -893,7 +893,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] ^ s; + } + return res; +@@ -970,14 +970,24 @@ + return res; + } + ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRight(&(*right)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mThis + mRight; ++ return res; ++#else ++ + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] + (*right)[i]; + } //C delete right; + return res; ++#endif + } + + template +@@ -1005,7 +1015,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*right)[i] + (*this)[i]; + } //C delete right; + return res; +@@ -1055,14 +1065,24 @@ + return res; + } + Ty s = (*right)[0]; ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mThis + s; ++ return res; ++#else ++ + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] + s; + } //C delete right; + return res; ++#endif ++ + } + template + BaseGDL* Data_::AddInvSNew( BaseGDL* r) +@@ -1086,7 +1106,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = s + (*this)[i]; + } //C delete right; + return res; +@@ -1145,25 +1165,44 @@ + Ty s; + if( right->StrictScalar(s)) + { ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mThis - s; ++ return res; ++#else + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] - s; + } ++ return res; ++#endif ++ + } + else + { ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRight(&(*right)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mThis - mRight; ++ return res; ++#else + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] - (*right)[i]; + } +- } + return res; ++#endif ++ } + } + // inverse substraction: left=right-left + template +@@ -1181,14 +1220,23 @@ + (*res)[0] = (*right)[0] - (*this)[0]; + return res; + } ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRight(&(*right)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mRight - mThis; ++ return res; ++#else + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*right)[i] - (*this)[i]; + } + return res; ++#endif + } + // invalid types + DStructGDL* DStructGDL::SubNew( BaseGDL* r) +@@ -1253,15 +1301,24 @@ + } + + Ty s = (*right)[0]; ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mThis - s; ++ return res; ++#else + + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] - s; + } + return res; ++#endif ++ + } + // inverse substraction: left=right-left + template +@@ -1282,14 +1339,23 @@ + Ty s = (*right)[0]; + // right->Scalar(s); + // dd = s - dd; ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = s - mThis; ++ return res; ++#else + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = s - (*this)[i]; + } + return res; ++#endif ++ + } + // invalid types + DStructGDL* DStructGDL::SubSNew( BaseGDL* r) +@@ -1359,7 +1425,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] > (*right)[i]) (*res)[i] = (*right)[i]; else (*res)[i] = (*this)[i]; + } //C delete right; + return res; +@@ -1421,7 +1487,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] > s) (*res)[i] = s; else (*res)[i] = (*this)[i]; + } //C delete right; + return res; +@@ -1485,7 +1551,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] < (*right)[i]) (*res)[i] = (*right)[i]; else (*res)[i] = (*this)[i]; + } //C delete right; + return res; +@@ -1547,7 +1613,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + if( (*this)[i] < s) (*res)[i] = s; else (*res)[i] = (*this)[i]; + } ; + return res; +@@ -1609,14 +1675,24 @@ + (*res)[0] = (*this)[0] * (*right)[0]; + return res; + } ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRight(&(*right)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mThis * mRight; ++ return res; ++#else + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = (*this)[i] * (*right)[i]; + } //C delete right; + return res; ++#endif ++ + } + // invalid types + DStructGDL* DStructGDL::MultNew( BaseGDL* r) +@@ -1659,14 +1735,23 @@ + return res; + } + Ty s = ( *right ) [0]; ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mThis * s; ++ return res; ++#else + TRACEOMP ( __FILE__, __LINE__ ) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for ( int i=0; i < nEl; ++i ) ++ for ( OMPInt i=0; i < nEl; ++i ) + (*res ) [i] = (*this )[i] * s; + } + return res; ++#endif ++ + } + // invalid types + DStructGDL* DStructGDL::MultSNew( BaseGDL* r) +@@ -1724,7 +1809,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + if( (*right)[ix] != this->zero) + (*res)[ix] = (*this)[ix] / (*right)[ix]; + else +@@ -1759,7 +1844,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + if( (*this)[ix] != this->zero) + (*res)[ix] = (*right)[ix] / (*this)[ix]; + else +@@ -1878,7 +1963,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + if( (*this)[ix] != this->zero) + (*res)[ix] = s / (*this)[ix]; + else +@@ -1963,7 +2048,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + if( (*right)[ix] != this->zero) + (*res)[ix] = (*this)[ix] % (*right)[ix]; + else +@@ -1996,7 +2081,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + if( (*this)[ix] != this->zero) + (*res)[ix] = (*right)[ix] % (*this)[ix]; + else +@@ -2032,7 +2117,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = Modulo((*this)[i],(*right)[i]); + } + return res; +@@ -2058,7 +2143,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = Modulo((*right)[i],(*this)[i]); + } + return res; +@@ -2090,7 +2175,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = Modulo((*this)[i],(*right)[i]); + } + return res; +@@ -2116,7 +2201,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = Modulo((*right)[i],(*this)[i]); + } + return res; +@@ -2260,7 +2345,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int ix=i; ix < nEl; ++ix) ++ for( OMPInt ix=i; ix < nEl; ++ix) + if( (*this)[ix] != this->zero) + (*res)[ix] = s % (*this)[ix]; + else +@@ -2289,7 +2374,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = Modulo((*this)[i],s); + } + return res; +@@ -2315,7 +2400,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = Modulo(s,(*this)[i]); + } + return res; +@@ -2340,7 +2425,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = Modulo((*this)[i],s); + } + return res; +@@ -2366,7 +2451,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = Modulo(s,(*this)[i]); + } + return res; +@@ -2491,7 +2576,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); // valarray + } //C delete right; + return res; +@@ -2515,7 +2600,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*right)[i], (*this)[i]); + } + return res; +@@ -2553,7 +2638,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], r0); + } return res; + } +@@ -2565,7 +2650,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[ i] = pow( s0, (*right)[ i]); + } return res; + } +@@ -2576,7 +2661,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } return res; + } +@@ -2587,7 +2672,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } return res; + } +@@ -2598,7 +2683,7 @@ + DLongGDL* right=static_cast(r); + + ULong rEl=right->N_Elements(); +- ULong nEl=N_Elements(); Data_* res = NewResult(); ++ ULong nEl=N_Elements(); + assert( rEl); + assert( nEl); + if( r->StrictScalar()) +@@ -2609,7 +2694,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], r0); + } return res; + } +@@ -2621,7 +2706,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[ i] = pow( s0, (*right)[ i]); + } return res; + } +@@ -2632,7 +2717,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } return res; + } +@@ -2643,7 +2728,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } return res; + } +@@ -2667,7 +2752,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } + return res; +@@ -2690,7 +2775,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*right)[i], (*this)[i]); + } //C delete right; + return res; +@@ -2713,7 +2798,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } + return res; +@@ -2737,7 +2822,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*right)[i], (*this)[i]); + } //C delete right; + return res; +@@ -2768,7 +2853,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } + return res; +@@ -2937,7 +3022,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*right)[i], (*this)[i]); + } + return res; +@@ -2967,7 +3052,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], (*right)[i]); + } + return res; +@@ -3131,7 +3216,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*right)[i], (*this)[i]); + } + return res; +@@ -3203,7 +3288,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( (*this)[i], s); + } + //C delete right; +@@ -3228,7 +3313,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = pow( s, (*this)[i]); + } //C delete right; + return res; +@@ -3257,7 +3342,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i ++// #include "sigfpehandler.hpp" ++// ++// #ifdef _OPENMP ++// #include ++// #endif ++// ++// #include "typetraits.hpp" ++// ++// using namespace std; ++ ++ ++// Sub ++// substraction: left=left-right ++template ++BaseGDL* Data_::Sub( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong rEl=right->N_Elements(); ++ ULong nEl=N_Elements(); ++ assert( rEl); ++ assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ if( nEl == 1) ++ { ++ (*this)[0] -= (*right)[0]; ++ return this; ++ } ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRight(&(*right)[0], nEl); ++ mThis -= mRight; ++ return this; ++#else ++ ++ if( nEl == rEl) ++ dd -= right->dd; ++ else ++ { ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] -= (*right)[i]; ++ }} //C delete right; ++ return this; ++#endif ++ ++} ++// inverse substraction: left=right-left ++template ++BaseGDL* Data_::SubInv( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong rEl=right->N_Elements(); ++ ULong nEl=N_Elements(); ++ assert( rEl); ++ assert( nEl); ++ // if( !rEl || !nEl) throw GDLException("Variable is undefined."); ++ /* if( nEl == rEl) ++ dd = right->dd - dd; ++ else*/ ++ if( nEl == 1) ++ { ++ (*this)[0] = (*right)[0] - (*this)[0]; ++ return this; ++ } ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRight(&(*right)[0], nEl); ++ mThis = mRight - mThis; ++ return this; ++#else ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] = (*right)[i] - (*this)[i]; ++ } //C delete right; ++ return this; ++#endif ++ ++} ++// invalid types ++DStructGDL* DStructGDL::Sub( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++DStructGDL* DStructGDL::SubInv( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::Sub( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::SubInv( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::Sub( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::SubInv( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++BaseGDL* Data_::Sub( BaseGDL* r) ++{ ++ // overload here ++ Data_* self; ++ DFun* plusOverload; ++ ++ ProgNodeP callingNode = interpreter->GetRetTree(); ++ ++ if( !Scalar()) ++ { ++ if( r->Type() == GDL_OBJ && r->Scalar()) ++ { ++ self = static_cast( r); ++ plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOMinus)); ++ if( plusOverload == NULL) ++ { ++ throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); ++ } ++ } ++ else ++ { ++ throw GDLException( callingNode, "Cannot apply operation to non-scalar datatype OBJECT.", true, false); ++ } ++ } ++ else ++ { ++ // Scalar() ++ self = static_cast( this); ++ plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOMinus)); ++ if( plusOverload == NULL) ++ { ++ if( r->Type() == GDL_OBJ && r->Scalar()) ++ { ++ self = static_cast( r); ++ plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOMinus)); ++ if( plusOverload == NULL) ++ { ++ throw GDLException(callingNode,"Cannot apply not overloaded operator to datatype OBJECT.",true, false); ++ } ++ } ++ else ++ { ++ throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); ++ } ++ } ++ } ++ ++ assert( self->Scalar()); ++ assert( plusOverload != NULL); ++ ++ // hidden SELF is counted as well ++ int nParSub = plusOverload->NPar(); ++ assert( nParSub >= 1); // SELF ++ if( nParSub < 3) // (SELF), LEFT, RIGHT ++ { ++ throw GDLException( callingNode, plusOverload->ObjectName() + ++ ": Incorrect number of arguments.", ++ false, false); ++ } ++ EnvUDT* newEnv; ++ Guard selfGuard; ++ BaseGDL* thisP; ++ // Dup() here is not optimal ++ // avoid at least for internal overload routines (which do/must not change SELF or r) ++ bool internalDSubUD = plusOverload->GetTree()->IsWrappedNode(); ++ if( internalDSubUD) ++ { ++ thisP = this; ++ newEnv= new EnvUDT( callingNode, plusOverload, &self); ++ newEnv->SetNextParUnchecked( &thisP); // LEFT parameter, as reference to prevent cleanup in newEnv ++ newEnv->SetNextParUnchecked( &r); // RVALUE parameter, as reference to prevent cleanup in newEnv ++ } ++ else ++ { ++ self = self->Dup(); ++ selfGuard.Init( self); ++ newEnv= new EnvUDT( callingNode, plusOverload, &self); ++ newEnv->SetNextParUnchecked( this->Dup()); // LEFT parameter, as value ++ newEnv->SetNextParUnchecked( r->Dup()); // RIGHT parameter, as value ++ } ++ ++ ++ // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack ++ StackGuard guard(interpreter->CallStack()); ++ ++ interpreter->CallStack().push_back( newEnv); ++ ++ // make the call ++ BaseGDL* res=interpreter->call_fun(static_cast(newEnv->GetPro())->GetTree()); ++ ++ if( !internalDSubUD && self != selfGuard.Get()) ++ { ++ // always put out warning first, in case of a later crash ++ Warning( "WARNING: " + plusOverload->ObjectName() + ++ ": Assignment to SELF detected (GDL session still ok)."); ++ // assignment to SELF -> self was deleted and points to new variable ++ // which it owns ++ selfGuard.Release(); ++ if( static_cast(self) != NullGDL::GetSingleInstance()) ++ selfGuard.Reset(self); ++ } ++ return res; ++} ++template<> ++BaseGDL* Data_::SubInv( BaseGDL* r) ++{ ++ if( r->Type() == GDL_OBJ && r->Scalar()) ++ { ++ return r->Sub( this); // for right order of parameters ++ } ++ ++ // overload here ++ Data_* self; ++ DFun* plusOverload; ++ ++ ProgNodeP callingNode = interpreter->GetRetTree(); ++ ++ if( !Scalar()) ++ { ++ throw GDLException( callingNode, "Cannot apply operation to non-scalar datatype OBJECT.", true, false); ++ } ++ else ++ { ++ // Scalar() ++ self = static_cast( this); ++ plusOverload = static_cast(GDLInterpreter::GetObjHeapOperator( (*self)[0], OOMinus)); ++ if( plusOverload == NULL) ++ { ++ throw GDLException( callingNode, "Cannot apply not overloaded operator to datatype OBJECT.", true, false); ++ } ++ } ++ ++ assert( self->Scalar()); ++ assert( plusOverload != NULL); ++ ++ // hidden SELF is counted as well ++ int nParSub = plusOverload->NPar(); ++ assert( nParSub >= 1); // SELF ++ if( nParSub < 3) // (SELF), LEFT, RIGHT ++ { ++ throw GDLException( callingNode, plusOverload->ObjectName() + ++ ": Incorrect number of arguments.", ++ false, false); ++ } ++ EnvUDT* newEnv; ++ Guard selfGuard; ++ BaseGDL* thisP; ++ // Dup() here is not optimal ++ // avoid at least for internal overload routines (which do/must not change SELF or r) ++ bool internalDSubUD = plusOverload->GetTree()->IsWrappedNode(); ++ if( internalDSubUD) ++ { ++ thisP = this; ++ newEnv= new EnvUDT( callingNode, plusOverload, &self); ++ // order different to Add ++ newEnv->SetNextParUnchecked( &r); // RVALUE parameter, as reference to prevent cleanup in newEnv ++ newEnv->SetNextParUnchecked( &thisP); // LEFT parameter, as reference to prevent cleanup in newEnv ++ } ++ else ++ { ++ self = self->Dup(); ++ selfGuard.Init( self); ++ newEnv= new EnvUDT( callingNode, plusOverload, &self); ++ // order different to Add ++ newEnv->SetNextParUnchecked( r->Dup()); // RIGHT parameter, as value ++ newEnv->SetNextParUnchecked( this->Dup()); // LEFT parameter, as value ++ } ++ ++ ++ // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack ++ StackGuard guard(interpreter->CallStack()); ++ ++ interpreter->CallStack().push_back( newEnv); ++ ++ // make the call ++ BaseGDL* res=interpreter->call_fun(static_cast(newEnv->GetPro())->GetTree()); ++ ++ if( !internalDSubUD && self != selfGuard.Get()) ++ { ++ // always put out warning first, in case of a later crash ++ Warning( "WARNING: " + plusOverload->ObjectName() + ++ ": Assignment to SELF detected (GDL session still ok)."); ++ // assignment to SELF -> self was deleted and points to new variable ++ // which it owns ++ selfGuard.Release(); ++ if( static_cast(self) != NullGDL::GetSingleInstance()) ++ selfGuard.Reset(self); ++ } ++ return res; ++} ++template ++Data_* Data_::SubS( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong nEl=N_Elements(); ++ assert( nEl); ++ if( nEl == 1) ++ { ++ (*this)[0] -= (*right)[0]; ++ return this; ++ } ++ ++ Ty s = (*right)[0]; ++ // right->Scalar(s); ++ // dd -= s; ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ mThis -= s; ++ return this; ++#else ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] -= s; ++ } //C delete right; ++ return this; ++#endif ++ ++} ++// inverse substraction: left=right-left ++template ++Data_* Data_::SubInvS( BaseGDL* r) ++{ ++ Data_* right=static_cast(r); ++ ++ ULong nEl=N_Elements(); ++ assert( nEl); ++ ++ if( nEl == 1) ++ { ++ (*this)[0] = (*right)[0] - (*this)[0]; ++ return this; ++ } ++ ++ Ty s = (*right)[0]; ++ // right->Scalar(s); ++ // dd = s - dd; ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mThis(&(*this)[0], nEl); ++ mThis = s - mThis; ++ return this; ++#else ++ TRACEOMP( __FILE__, __LINE__) ++#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++#pragma omp for ++ for( OMPInt i=0; i < nEl; ++i) ++ (*this)[i] = s - (*this)[i]; ++ } //C delete right; ++ return this; ++#endif ++ ++} ++// invalid types ++DStructGDL* DStructGDL::SubS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++DStructGDL* DStructGDL::SubInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRUCT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::SubS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::SubInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype STRING.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::SubS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::SubInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype PTR.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::SubS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++template<> ++Data_* Data_::SubInvS( BaseGDL* r) ++{ ++ throw GDLException("Cannot apply operation to datatype OBJECT.",true,false); ++ return this; ++} ++ ++ ++#endif diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_pro.cpp gdl/src/basic_pro.cpp --- gdl-0.9.3/src/basic_pro.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/basic_pro.cpp 2013-02-25 17:04:24.629180969 -0700 ++++ gdl/src/basic_pro.cpp 2013-03-21 14:04:04.285825602 -0600 @@ -241,6 +241,51 @@ { bool kw = false; @@ -3387,6 +22213,15 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_pro.cpp gdl e->Catch(); } +@@ -1709,7 +1754,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; iNParam(); @@ -3494,6 +22329,421 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_pro.cpp gdl } Only in gdl-0.9.3/src: .#basic_pro.cpp.1.103 +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/basic_pro_jmg.cpp gdl/src/basic_pro_jmg.cpp +--- gdl-0.9.3/src/basic_pro_jmg.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/basic_pro_jmg.cpp 2013-03-21 14:04:04.286825597 -0600 +@@ -386,7 +386,7 @@ + ); + } + +- if (IsNumericType[pType]) { ++ if (NumericType(pType)) { + if (par->Sizeof() > sizeof(void*)) { + e->Throw("Parameter is larger than pointer: " + + e->GetParString(i) +@@ -407,7 +407,7 @@ + argv[i-2] = (void*) par; + } + else { // By reference (default) +- if (IsNumericType[pType] || pType == GDL_PTR || pType == GDL_OBJ ) { ++ if (NumericType(pType) || pType == GDL_PTR || pType == GDL_OBJ ) { + argv[i-2] = (void*) par->DataAddr(); + } + else if (pType == GDL_STRING) { +@@ -606,7 +606,7 @@ + SizeT sizeOf; + void* source; + int doFree = 0; +- if (IsNumericType[pType] || pType == GDL_PTR || pType == GDL_OBJ) { ++ if (NumericType(pType) || pType == GDL_PTR || pType == GDL_OBJ) { + source = (void*) member->DataAddr(); + length = member->NBytes(); + sizeOf = member->Sizeof(); +@@ -658,7 +658,7 @@ + SizeT length; + SizeT sizeOf; + void* dest; +- if (IsNumericType[pType]) { ++ if (NumericType(pType)) { + sizeOf = member->Sizeof(); + } + else { +@@ -670,7 +670,7 @@ + p += space; + } + +- if (IsNumericType[pType] || pType == GDL_PTR || pType == GDL_OBJ) { ++ if (NumericType(pType) || pType == GDL_PTR || pType == GDL_OBJ) { + length = member->NBytes(); + dest = (void*) member->DataAddr(); + memcpy(dest, p, length); +@@ -709,7 +709,7 @@ + for (SizeT iTag=0; iTag < nTags; iTag++) { + BaseGDL* member = s->GetTag(iTag); + DType pType = member->Type(); +- if (IsNumericType[pType] || pType == GDL_PTR || pType == GDL_OBJ) { ++ if (NumericType(pType) || pType == GDL_PTR || pType == GDL_OBJ) { + totalSize += member->NBytes(); + sizeOf = member->Sizeof(); + } +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/CFMTLexer.cpp gdl/src/CFMTLexer.cpp +--- gdl-0.9.3/src/CFMTLexer.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/CFMTLexer.cpp 2013-03-21 14:04:03.940827197 -0600 +@@ -1,6 +1,7 @@ + /* $ANTLR 2.7.7 (20110618): "cformat.g" -> "CFMTLexer.cpp"$ */ + + #include "includefirst.hpp" ++#include + + #include "CFMTLexer.hpp" + #include +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/cformat.g gdl/src/cformat.g +--- gdl-0.9.3/src/cformat.g 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/cformat.g 2013-03-21 14:04:04.287825593 -0600 +@@ -17,6 +17,7 @@ + + header "pre_include_cpp" { + #include "includefirst.hpp" ++#include + } + + header { +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/convert2.cpp gdl/src/convert2.cpp +--- gdl-0.9.3/src/convert2.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/convert2.cpp 2013-03-21 14:04:04.289825584 -0600 +@@ -447,7 +447,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=i2s((*this)[i],8); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -617,7 +617,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=i2s((*this)[i],8); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -790,7 +790,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=i2s((*this)[i],12); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -963,7 +963,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=i2s((*this)[i],12); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1034,7 +1034,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2DByte((*this)[i]); + } //(*dest)[i]=Real2DByte((*this)[i]); + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1055,7 +1055,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int((*this)[i]); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1096,7 +1096,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int((*this)[i]); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1139,7 +1139,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int((*this)[i]); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1187,7 +1187,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=float2string((*this)[i]); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1259,7 +1259,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2DByte((*this)[i]); + //(*dest)[i]=Double2DByte((*this)[i]); + } +@@ -1282,7 +1282,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int((*this)[i]); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1325,7 +1325,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int((*this)[i]); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1368,7 +1368,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int((*this)[i]); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1416,7 +1416,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=double2string((*this)[i]); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1502,7 +1502,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + SizeT basePtr = i*maxLen; + +@@ -1521,7 +1521,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1550,7 +1550,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1579,7 +1579,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1608,7 +1608,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1637,7 +1637,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1666,7 +1666,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1695,7 +1695,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1724,7 +1724,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1754,7 +1754,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1784,7 +1784,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) shared( errorFlag, mode) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + { + const char* cStart=(*this)[i].c_str(); + char* cEnd; +@@ -1846,7 +1846,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2DByte(real((*this)[i])); + } //(*dest)[i]=Real2DByte(real((*this)[i])); + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1868,7 +1868,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int(real((*this)[i])); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1911,7 +1911,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int(real((*this)[i])); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -1954,7 +1954,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int(real((*this)[i])); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -2030,7 +2030,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]="("+i2s(real((*this)[i]))+","+i2s(imag((*this)[i]))+")"; + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -2090,7 +2090,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2DByte(real((*this)[i])); + } //(*dest)[i]=Double2DByte(real((*this)[i])); + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -2112,7 +2112,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int(real((*this)[i])); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -2155,7 +2155,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int(real((*this)[i])); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -2198,7 +2198,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=Real2Int(real((*this)[i])); + if( (mode & BaseGDL::CONVERT) != 0) delete this; + } +@@ -2274,7 +2274,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]="("+i2s(real((*this)[i]))+","+i2s(imag((*this)[i]))+")"; + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -2445,7 +2445,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=i2s((*this)[i],22); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; +@@ -2617,7 +2617,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*dest)[i]=i2s((*this)[i],22); + } + if( (mode & BaseGDL::CONVERT) != 0) delete this; diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/convol.opt.cpp gdl/src/convol.opt.cpp --- gdl-0.9.3/src/convol.opt.cpp 1969-12-31 17:00:00.000000000 -0700 +++ gdl/src/convol.opt.cpp 2004-12-09 08:10:19.000000000 -0700 @@ -4407,8 +23657,295 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/convol.sav.cpp gd + diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl/src/datatypes.cpp --- gdl-0.9.3/src/datatypes.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/datatypes.cpp 2013-02-25 17:04:24.700180680 -0700 -@@ -5279,7 +5279,7 @@ ++++ gdl/src/datatypes.cpp 2013-03-21 14:04:04.293825565 -0600 +@@ -249,11 +249,23 @@ + const size_t newSize = multiAlloc - 1; + + freeList.resize( newSize); +- char* res = static_cast< char*>( malloc( sizeof( Data_) * multiAlloc)); // one more than newSize ++ ++#ifdef USE_EIGEN ++ // we need this allocation here as well (as in typedefs.hpp), because GDLArray needs to be aligned ++ const int alignmentInBytes = 16; // set to multiple of 16 >= sizeof( char*) ++ const size_t realSizeOfType = sizeof( Data_); ++ const SizeT exceed = realSizeOfType % alignmentInBytes; ++ const size_t sizeOfType = realSizeOfType + (alignmentInBytes - exceed); ++ char* res = static_cast< char*>( Eigen::internal::aligned_malloc( sizeOfType * multiAlloc)); // one more than newSize ++#else ++ const size_t sizeOfType = sizeof( Data_); ++ char* res = static_cast< char*>( malloc( sizeOfType * multiAlloc)); // one more than newSize ++#endif ++ + for( size_t i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for*/ +- for( int i = 0; i + void Data_::Construct() +-{} +-template<> +-void Data_::Construct() + { ++ const bool isPOD = Sp::IS_POD; ++ // do nothing for POD ++ if( !isPOD) ++ { + SizeT nEl = dd.size(); + // for( SizeT i = 0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for*/ +- for( int i = 0; i +-void Data_::Construct() ++void Data_::Construct() + { + SizeT nEl = dd.size(); + // for( SizeT i = 0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for*/ +- for( int i = 0; i +-void Data_< SpDString>::Construct() +-{ ++void Data_::Construct() ++{ + SizeT nEl = dd.size(); + // for( SizeT i = 0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for*/ +- for( int i = 0; i +-void Data_< SpDComplex>::Construct() +-{ +- SizeT nEl = dd.size(); +- /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- #pragma omp for*/ +- for( int i = 0; i +-void Data_< SpDComplexDbl>::Construct() +-{ +- SizeT nEl = dd.size(); +- /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- #pragma omp for*/ +- for( int i = 0; i ++// void Data_< SpDString>::Construct() ++// { ++// SizeT nEl = dd.size(); ++// // for( SizeT i = 0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( SizeT i = 0; i ++// void Data_< SpDComplex>::Construct() ++// { ++// SizeT nEl = dd.size(); ++// /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( SizeT i = 0; i ++// void Data_< SpDComplexDbl>::Construct() ++// { ++// SizeT nEl = dd.size(); ++// /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( SizeT i = 0; i + void Data_::ConstructTo0() + { ++ if( Sp::IS_POD) ++ { + SizeT nEl = dd.size(); + /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for*/ +- for( int i = 0; i +-void Data_< SpDString>::ConstructTo0() +-{ +- SizeT nEl = dd.size(); +- /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- #pragma omp for*/ +- for( int i = 0; i +-void Data_< SpDComplex>::ConstructTo0() +-{ +- SizeT nEl = dd.size(); +- /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- #pragma omp for*/ +- for( int i = 0; i +-void Data_< SpDComplexDbl>::ConstructTo0() +-{ ++ for( SizeT i = 0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for*/ +- for( int i = 0; i ++// void Data_< SpDString>::ConstructTo0() ++// { ++// SizeT nEl = dd.size(); ++// /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( int i = 0; i ++// void Data_< SpDComplex>::ConstructTo0() ++// { ++// SizeT nEl = dd.size(); ++// /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( int i = 0; i ++// void Data_< SpDComplexDbl>::ConstructTo0() ++// { ++// SizeT nEl = dd.size(); ++// /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( int i = 0; i + void Data_::Destruct() + { + // no destruction for POD ++ if( !Sp::IS_POD) ++ { ++ SizeT nEl = dd.size(); ++ /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++ { ++ #pragma omp for*/ ++ for( SizeT i = 0; i + void Data_< SpDPtr>::Destruct() +@@ -1885,36 +1929,36 @@ + { + GDLInterpreter::DecRefObj( this); + } +-template<> +-void Data_< SpDString>::Destruct() +-{ +- SizeT nEl = dd.size(); +- /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- #pragma omp for*/ +- for( int i = 0; i +-void Data_< SpDComplex>::Destruct() +-{ +- SizeT nEl = dd.size(); +- /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- #pragma omp for*/ +- for( int i = 0; i +-void Data_< SpDComplexDbl>::Destruct() +-{ +- SizeT nEl = dd.size(); +- /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { +- #pragma omp for*/ +- for( int i = 0; i ++// void Data_< SpDString>::Destruct() ++// { ++// SizeT nEl = dd.size(); ++// /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( SizeT i = 0; i ++// void Data_< SpDComplex>::Destruct() ++// { ++// SizeT nEl = dd.size(); ++// /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( SizeT i = 0; i ++// void Data_< SpDComplexDbl>::Destruct() ++// { ++// SizeT nEl = dd.size(); ++// /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) ++// { ++// #pragma omp for*/ ++// for( SizeT i = 0; i + BaseGDL* Data_::SetBuffer( const void* b) +@@ -5279,7 +5323,7 @@ SizeT Data_::GetAsIndexStrict( SizeT i) const { if( (*this)[i] < 0) @@ -4417,7 +23954,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl "contains out of range (<0) subscript (at index: " + i2s(i) + ").",true,false); return (*this)[i]; } -@@ -5294,7 +5294,7 @@ +@@ -5294,7 +5338,7 @@ SizeT Data_::GetAsIndexStrict( SizeT i) const { if( (*this)[i] < 0) @@ -4426,7 +23963,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl "contains out of range (<0) subscript (at index: " + i2s(i) + ").",true,false); return (*this)[i]; } -@@ -5309,7 +5309,7 @@ +@@ -5309,7 +5353,7 @@ SizeT Data_::GetAsIndexStrict( SizeT i) const { if( (*this)[i] < 0) @@ -4435,7 +23972,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl "contains out of range (<0) subscript (at index: " + i2s(i) + ").",true,false); return (*this)[i]; } -@@ -5324,7 +5324,7 @@ +@@ -5324,7 +5368,7 @@ SizeT Data_::GetAsIndexStrict( SizeT i) const { if( (*this)[i] <= -1.0) @@ -4444,7 +23981,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl "contains out of range (<0) subscript (at index: " + i2s(i) + ").",true,false); if( (*this)[i] <= 0.0) return 0; -@@ -5341,7 +5341,7 @@ +@@ -5341,7 +5385,7 @@ SizeT Data_::GetAsIndexStrict( SizeT i) const { if( (*this)[i] <= -1.0) @@ -4453,7 +23990,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl "contains out of range (<0) subscript (at index: " + i2s(i) + ").",true,false); if( (*this)[i] <= 0.0) return 0; -@@ -5374,7 +5374,7 @@ +@@ -5374,7 +5418,7 @@ return 0; } if( l < 0) @@ -4462,7 +23999,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl "contains out of range (<0) subscript.",true,false); return l; } -@@ -5390,7 +5390,7 @@ +@@ -5390,7 +5434,7 @@ SizeT Data_::GetAsIndexStrict( SizeT i) const { if( real((*this)[i]) <= -1.0) @@ -4471,7 +24008,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl "contains out of range (<0) subscript (at index: " + i2s(i) + ").",true,false); if( real((*this)[i]) <= 0.0) return 0; -@@ -5407,7 +5407,7 @@ +@@ -5407,7 +5451,7 @@ SizeT Data_::GetAsIndexStrict( SizeT i) const { if( real((*this)[i]) <= -1.0) @@ -4480,24 +24017,71 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.cpp gdl "contains out of range (<0) subscript (at index: " + i2s(i) + ").",true,false); if( real((*this)[i]) <= 0.0) return 0; +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypes.hpp gdl/src/datatypes.hpp +--- gdl-0.9.3/src/datatypes.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/datatypes.hpp 2013-03-21 14:04:04.295825556 -0600 +@@ -53,8 +53,12 @@ + #endif + + typedef typename Sp::DataT DataT; ++#ifdef USE_EIGEN ++ EIGEN_ALIGN16 DataT dd; // the data ++#else + DataT dd; // the data +- ++#endif ++ + public: + // memory management optimization + static std::deque< void*> freeList; +@@ -141,7 +145,7 @@ + void Clear(); + void Construct(); // construction (for DStructGDL) + void ConstructTo0(); // construction (for DStructGDL) +- void Destruct(); // destruction (for DStructGDL) ++ void Destruct(); // destruction (for DStructGDL) + + BaseGDL* SetBuffer( const void* b); + void SetBufferSize( SizeT s); +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/datatypesref.cpp gdl/src/datatypesref.cpp +--- gdl-0.9.3/src/datatypesref.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/datatypesref.cpp 2013-03-21 14:04:04.297825547 -0600 +@@ -31,7 +31,7 @@ + /*#pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for*/ +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for*/ +- for( int i=0; iInitTag("NAME", DStringGDL( name)); @@ -4675,7 +24259,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/deviceps.hpp gdl/ SetPortrait(); -@@ -325,6 +355,10 @@ +@@ -325,6 +356,10 @@ = DLong(floor(0.5+ xs * (*static_cast(dStruct->GetTag(dStruct->Desc()->TagIndex("X_PX_CM"))))[0] )); @@ -4686,7 +24270,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/deviceps.hpp gdl/ return true; } -@@ -335,32 +369,36 @@ +@@ -335,32 +370,36 @@ = DLong(floor(0.5+ ys * (*static_cast(dStruct->GetTag(dStruct->Desc()->TagIndex("Y_PX_CM"))))[0] )); @@ -4733,7 +24317,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/deviceps.hpp gdl/ return true; } -@@ -404,8 +442,8 @@ +@@ -404,8 +443,8 @@ DDouble xmin, ymin; { DDouble null; @@ -5200,7 +24784,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/devicez.hpp gdl/s SizeT rank = p0B->Rank(); diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/dinterpreter.cpp gdl/src/dinterpreter.cpp --- gdl-0.9.3/src/dinterpreter.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/dinterpreter.cpp 2013-02-25 17:04:24.755180455 -0700 ++++ gdl/src/dinterpreter.cpp 2013-03-21 14:04:04.301825528 -0600 @@ -113,14 +113,14 @@ return static_cast( this)->InnerInterpreterLoop(lineOffset); } @@ -5318,8 +24902,8 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/dinterpreter.cpp + true,false); + } + } - } - ++} ++ +void GDLInterpreter::SetRootR( ProgNodeP tt, DotAccessDescT* aD, BaseGDL* r, ArrayIndexListT* aL) +{ +// check here for object and get struct @@ -5402,8 +24986,8 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/dinterpreter.cpp + " STRUCT in this context: "+Name(r),true,false); + } + } -+} -+ + } + +// DStructDesc* GDLInterpreter::GDLObjectDesc( DStructGDL* oStruct, ProgNodeP mp) +// { +// //DStructGDL* oStruct = ObjectStruct( self, mp); @@ -5437,6 +25021,96 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/dinterpreter.cpp // searches and compiles procedure (searchForPro == true) or function (searchForPro == false) 'pro' bool GDLInterpreter::SearchCompilePro(const string& pro, bool searchForPro) { +@@ -771,6 +949,20 @@ + return ExecuteCommand( line.substr(1)); + } + ++ // command ++ if( firstChar == "?") ++ { ++ // later, we will have to check whether we have X11/Display or not ++ // on some computing nodes on supercomputers, this is de-activated. ++ if (line.substr(1).length() > 0) { ++ line=line.substr(1); ++ StrTrim(line); ++ line="online_help, '"+line+"'"; //' ++ } else { ++ line="online_help"; ++ } ++ } ++ + // shell command + if( firstChar == "$") + { +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/dpro.hpp gdl/src/dpro.hpp +--- gdl-0.9.3/src/dpro.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/dpro.hpp 2013-03-21 14:04:04.302825523 -0600 +@@ -115,14 +115,14 @@ + // N=size(key) + // K=size(var)-nPar-N + IDList key; // keyword names (IDList: typedefs.hpp) +- // (KEYWORD_NAME=keyword_value) ++ // (KEYWORD_NAME=keyword_value) + int nPar; // number of parameters (-1 = infinite) + int nParMin; // minimum number of parameters (-1 = infinite) + + ExtraType extra; + int extraIx; // index of extra keyword + +- IDList warnKey; // keyword names to accept but warn ++ IDList warnKey; // keyword names to accept but warn + // (IDList: typedefs.hpp) + + public: +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/dstructdesc.hpp gdl/src/dstructdesc.hpp +--- gdl-0.9.3/src/dstructdesc.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/dstructdesc.hpp 2013-03-21 14:04:04.303825519 -0600 +@@ -18,6 +18,8 @@ + #ifndef DSTRUCTDESC_HPP_ + #define DSTRUCTDESC_HPP_ + ++#include "includefirst.hpp" // USE_EIGEN3 ++ + #include + #include + #include +@@ -43,11 +45,16 @@ + // and DStringGDL (considers actual string sizes) + SizeT nBytes = tags.back()->NBytes(); + +- // alignment +- const int sizeOfPtr = sizeof( char*); +- SizeT exceed = nBytes % sizeOfPtr; ++ // alignment ++#ifdef USE_EIGEN3 ++ assert( sizeof( char*) <= 16); ++ const int alignmentInBytes = 16; // set to multiple of 16 >= sizeof( char*) ++#else ++ const int alignmentInBytes = sizeof( char*); ++#endif ++ SizeT exceed = nBytes % alignmentInBytes; + if( exceed > 0) +- nBytes += sizeOfPtr - exceed; ++ nBytes += alignmentInBytes - exceed; + + // valid tagOffset (used by NBytes()) + tagOffset.push_back( tagOffset.back() + nBytes); +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/dstructgdl.hpp gdl/src/dstructgdl.hpp +--- gdl-0.9.3/src/dstructgdl.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/dstructgdl.hpp 2013-03-21 14:04:04.304825514 -0600 +@@ -43,7 +43,11 @@ + + //public: + std::deque typeVar; // for accessing data +- DataT dd; // the data ++#ifdef USE_EIGEN ++ EIGEN_ALIGN16 DataT dd; // the data ++#else ++ DataT dd; // the data ++#endif + + void InitTypeVar( SizeT t) + { diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/envt.cpp gdl/src/envt.cpp --- gdl-0.9.3/src/envt.cpp 2012-12-27 09:22:44.000000000 -0700 +++ gdl/src/envt.cpp 2013-02-25 17:04:24.772180386 -0700 @@ -5484,7 +25158,27 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/envt.cpp gdl/src/ const string unnamed(""); diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/envt.hpp gdl/src/envt.hpp --- gdl-0.9.3/src/envt.hpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/envt.hpp 2013-02-25 17:04:24.773180382 -0700 ++++ gdl/src/envt.hpp 2013-03-21 14:04:04.305825510 -0600 +@@ -343,7 +343,7 @@ + return; + } + // this should never happen (or only in extreme rarely cases) +- // hence the performance will go down ++ // the performance will go down + // s > defaultLength + T* newArr = new T[ s]; // ctor called + if( eArr != reinterpret_cast(buf)) +@@ -368,8 +368,8 @@ + // T operator[]( SizeT i) const { assert( i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i ++class GDLArray ++{ ++private: ++ enum GDLArrayConstants ++ { ++ smallArraySize = 27, ++ maxCache = 1000 * 1000 // ComplexDbl is 16 bytes ++ }; ++ ++ typedef T Ty; ++ ++#ifdef USE_EIGEN ++ EIGEN_ALIGN16 char scalarBuf[ smallArraySize * sizeof(Ty)]; ++#else ++ char scalarBuf[ smallArraySize * sizeof(Ty)]; ++#endif ++ ++ Ty* InitScalar() ++ { ++ assert( sz <= smallArraySize); ++ if( IsPOD) ++ { ++ return reinterpret_cast(scalarBuf); ++ } ++ else ++ { ++ Ty* b = reinterpret_cast(scalarBuf); ++ for( int i = 0; i( s); ++#else ++ return new Ty[ s]; ++#endif ++ } ++ ++public: ++ GDLArray() throw() : buf( NULL), sz( 0) {} ++ ++#ifndef GDLARRAY_CACHE ++ ++ ~GDLArray() throw() ++ { ++ if( IsPOD) ++ { ++#ifdef USE_EIGEN ++ if( buf != reinterpret_cast(scalarBuf)) ++ Eigen::internal::aligned_delete( buf, sz); ++#else ++ if( buf != reinterpret_cast(scalarBuf)) ++ delete[] buf; // buf == NULL also possible ++#endif ++ // no cleanup of "buf" here ++ } ++ else ++ { ++#ifdef USE_EIGEN ++ if( buf != reinterpret_cast(scalarBuf)) ++ Eigen::internal::aligned_delete( buf, sz); ++ else ++ for( int i = 0; i(scalarBuf)) ++ delete[] buf; // buf == NULL also possible ++ else ++ for( int i = 0; i smallArraySize) ? New(cp.size()) /*New T[ cp.size()]*/ : InitScalar(); ++ } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } ++ ++ std::memcpy(buf,cp.buf,sz*sizeof(T)); ++ } ++ else ++ { ++ try { ++ buf = (cp.size() > smallArraySize) ? New(cp.size()) /*new Ty[ cp.size()]*/ : InitScalar(); ++ } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } ++ for( SizeT i=0; i smallArraySize) ? New(s) /*T[ s]*/ : InitScalar(); ++ } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } ++ } ++ ++ GDLArray( T val, SizeT s) : sz( s) ++ { ++ try { ++ buf = (s > smallArraySize) ? New(s) /*T[ s]*/ : InitScalar(); ++ } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } ++ ++ for( SizeT i=0; i smallArraySize ) ? New(s) /*T[ s]*/: InitScalar(); ++ } ++ catch ( std::bad_alloc& ) { ThrowGDLException ( "Array requires more memory than available" ); } ++ ++ std::memcpy(buf,arr,sz*sizeof(T)); ++ } ++ else ++ { ++ try { ++ buf = (s > smallArraySize) ? New(s) /*new Ty[ s]*/: InitScalar(); ++ } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } ++ for( SizeT i=0; i(scalarBuf); ++ buf[0] = s; ++ } ++ else ++ { ++ Ty* b = reinterpret_cast(scalarBuf); ++ new (&(b[ 0])) Ty( s); ++ buf = b; ++ } ++ } ++ ++ T& operator[]( SizeT ix) throw() ++ { ++ // if( ix >= sz) ++ assert( ix < sz); ++ return buf[ ix]; ++ } ++ const T& operator[]( SizeT ix) const throw() ++ { ++// if( ix >= sz) // debug ++ assert( ix < sz); ++ return buf[ ix]; ++ } ++ ++// private: // disable ++// only used (indirect) by DStructGDL::DStructGDL(const DStructGDL& d_) ++void InitFrom( const GDLArray& right ) ++{ ++ assert( &right != this); ++ assert ( sz == right.size() ); ++ if( IsPOD) ++ { ++ std::memcpy(buf,right.buf,sz*sizeof(Ty)); ++ } ++ else ++ { ++ for ( SizeT i=0; i smallArraySize ) ++ { ++ try ++ { ++ buf = New(sz) /*new T[ newSz]*/; ++ } ++ catch ( std::bad_alloc& ) ++ { ++ ThrowGDLException ( "Array requires more memory than available" ); ++ } ++ } ++ else ++ { ++ // default constructed instances have buf == NULL and size == 0 ++ // make sure buf is set corectly if such instances are resized ++ buf = InitScalar(); ++ } ++ } ++ ++}; // GDLArray ++ ++#endif diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gdlc.i.g gdl/src/gdlc.i.g --- gdl-0.9.3/src/gdlc.i.g 2012-12-27 09:22:44.000000000 -0700 +++ gdl/src/gdlc.i.g 2013-02-25 17:04:24.797180284 -0700 @@ -6168,7 +26209,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gdlexception.hpp // warnings ignore !QUIET diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gdlgstream.cpp gdl/src/gdlgstream.cpp --- gdl-0.9.3/src/gdlgstream.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/gdlgstream.cpp 2013-02-25 17:04:24.815180211 -0700 ++++ gdl/src/gdlgstream.cpp 2013-03-21 14:04:04.308825496 -0600 @@ -103,12 +103,15 @@ SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("NAME"), 0) ))[0]; @@ -6202,9 +26243,10 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gdlgstream.cpp gd + // set subpage numbers in X and Y +// plstream::ssub( nx, ny ); // ssub does not change charsize it seems + ssub( nx, ny ); ++ DLong pMod = (*pMulti)[0] % (nx*ny); + -+ if( (*pMulti)[0] <= 0 || (*pMulti)[0] == nx*ny) // clear and restart to first subpage -+ // if( (*pMulti)[0] <= 0) ++// if( (*pMulti)[0] <= 0 || (*pMulti)[0] == nx*ny) // clear and restart to first subpage ++ if( pMod == 0 ) // clear and restart to first subpage + { + if( erase ) { @@ -6226,7 +26268,6 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gdlgstream.cpp gd + } else + { -+ DLong pMod = (*pMulti)[0] % (nx*ny); + if( dir == 0 ) { - DLong pMod = (*pMulti)[ 0] % (nx*ny); @@ -6386,7 +26427,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gdlgstream.cpp gd +} diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gdlgstream.hpp gdl/src/gdlgstream.hpp --- gdl-0.9.3/src/gdlgstream.hpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/gdlgstream.hpp 2013-02-25 17:04:24.831180145 -0700 ++++ gdl/src/gdlgstream.hpp 2013-03-21 14:04:04.309825491 -0600 @@ -18,6 +18,9 @@ #ifndef GDLGSTREAM_HPP_ #define GDLGSTREAM_HPP_ @@ -6524,7 +26565,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gdlgstream.hpp gd virtual void Lower() {} virtual void Iconic() {} virtual void DeIconic() {} -+ virtual bool GetGin(PLGraphicsIn *gin, int mode) {} ++ virtual bool GetGin(PLGraphicsIn *gin, int mode) {return 0;} + virtual void WarpPointer(DLong x, DLong y){} + virtual void Flush() {} virtual void Clear() {} @@ -7612,6 +27653,42 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gshhs.cpp gdl/src actStream->NoSub(); +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/gsl_fun.cpp gdl/src/gsl_fun.cpp +--- gdl-0.9.3/src/gsl_fun.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/gsl_fun.cpp 2013-03-21 14:04:04.312825477 -0600 +@@ -1350,6 +1350,22 @@ + } + #endif + ++ // Alain C., 26 February 2013 ++ // this is a temporary workaround of an in accuracy in the GSL (up to 1.15) ++ // when working on 64b version and integer bin size ... ++ // GDL bug report 618683 ++ // http://sourceforge.net/tracker/?func=detail&aid=3602623&group_id=97659&atid=618683 ++ // GSL bug report thread ++ // http://lists.gnu.org/archive/html/bug-gsl/2013-02/msg00006.html ++ ++ static void gdl_make_uniform (gsl_histogram * h, size_t n, double xmin, double xmax) ++ { ++ size_t i; ++ for (i = 0; i <= n; i++) ++ h->range[i] = xmin + (double) i * (xmax-xmin)/((double) n); ++ } ++ ++ + BaseGDL* histogram_fun( EnvT* e) + { + double a; +@@ -1502,6 +1518,9 @@ + GDLGuard hhGuard( hh, gsl_histogram_free); + gsl_histogram_set_ranges_uniform( hh, a, b); + ++ // temporary revisited computation of bin values ... ++ gdl_make_uniform (hh, hh->n, a, b); ++ + // Set maxVal from keyword if present + if (maxKW != NULL) e->AssureDoubleScalarKW(e->KeywordIx("MAX"), maxVal); + diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/image.cpp gdl/src/image.cpp --- gdl-0.9.3/src/image.cpp 2012-12-27 09:22:44.000000000 -0700 +++ gdl/src/image.cpp 2013-02-25 17:04:24.977179550 -0700 @@ -7715,6 +27792,28 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/image.hpp gdl/src #include "envt.hpp" +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/includefirst.hpp gdl/src/includefirst.hpp +--- gdl-0.9.3/src/includefirst.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/includefirst.hpp 2013-03-21 14:04:04.313825472 -0600 +@@ -24,7 +24,6 @@ + //#else + //#error "config.h required. Compile with -DHAVE_CONFIG_H" + //#endif +- + #ifdef _MSC_VER + #define NOMINMAX + #endif +@@ -58,6 +57,10 @@ + //#if defined(USE_PYTHON) || defined(PYTHON_MODULE) + #endif + ++#if defined(USE_EIGEN) ++#include ++#endif ++ + #if defined(__sun__) + // SA: CS is defined in /usr/include/sys/regset.h and used in an enum statement by ANTLR + # include diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/initsysvar.cpp gdl/src/initsysvar.cpp --- gdl-0.9.3/src/initsysvar.cpp 2012-12-27 09:22:44.000000000 -0700 +++ gdl/src/initsysvar.cpp 2013-02-25 17:04:24.989179501 -0700 @@ -7768,7 +27867,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/io.cpp gdl/src/io } diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/libinit_ac.cpp gdl/src/libinit_ac.cpp --- gdl-0.9.3/src/libinit_ac.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/libinit_ac.cpp 2013-02-25 17:04:25.037179305 -0700 ++++ gdl/src/libinit_ac.cpp 2013-03-21 14:04:04.325825417 -0600 @@ -68,8 +68,6 @@ const string fx_rootKey[]={"DOUBLE","ITMAX","STOP","TOL",KLISTEND}; new DLibFun(lib::fx_root_fun,string("FX_ROOT"),2,fx_rootKey); @@ -7790,7 +27889,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/libinit_ac.cpp gd diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/libinit.cpp gdl/src/libinit.cpp --- gdl-0.9.3/src/libinit.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/libinit.cpp 2013-02-25 17:04:25.035179314 -0700 ++++ gdl/src/libinit.cpp 2013-03-21 14:04:04.322825431 -0600 @@ -200,8 +200,8 @@ const string helpKey[]={"STRUCTURES","ROUTINES","BRIEF", @@ -7830,9 +27929,10 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/libinit.cpp gdl/s - "XOFFSET", "YOFFSET", "ENCAPSULATED", KLISTEND + "XOFFSET", "YOFFSET", "ENCAPSULATED", "GET_GRAPHICS_FUNCTION", + "SET_GRAPHICS_FUNCTION", "CURSOR_STANDARD", "CURSOR_ORIGINAL", -+ "CURSOR_CROSSHAIR",KLISTEND ++ "CURSOR_CROSSHAIR","RETAIN", KLISTEND }; - const string deviceWarnKey[] = {"RETAIN", "SET_FONT", "HELVETICA", +- const string deviceWarnKey[] = {"RETAIN", "SET_FONT", "HELVETICA", ++ const string deviceWarnKey[] = {"SET_FONT", "HELVETICA", "AVANTGARDE", "BKMAN", "COURIER", "PALATINO", "SCHOOLBOOK", "TIMES", "ZAPFCHANCERY", "ZAPFDINGBATS", "BITS_PER_PIXEL", - "ITALIC", "BOLD", "TRUE_COLOR", KLISTEND}; @@ -8063,8 +28163,31 @@ Only in gdl-0.9.3/src: .#libinit.cpp.1.150 Only in gdl-0.9.3/src: .#libinit.cpp.1.151 diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/libinit_jmg.cpp gdl/src/libinit_jmg.cpp --- gdl-0.9.3/src/libinit_jmg.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/libinit_jmg.cpp 2013-02-25 17:04:25.040179293 -0700 -@@ -255,8 +255,9 @@ ++++ gdl/src/libinit_jmg.cpp 2013-03-21 14:04:04.333825380 -0600 +@@ -140,6 +140,22 @@ + "GRAY","LINEAR","NRHO","NTHETA","NX","NY", + "RHO","RMIN","THETA","XMIN","YMIN",KLISTEND}; + new DLibFun(lib::radon_fun,string("RADON"),1,radonKey); ++#ifdef PL_HAVE_QHULL ++ const string triangulateKey[]={"CONNECTIVITY", "SPHERE", "DEGREES", "FVALUE", "REPEATS", "TOLERANCE",KLISTEND}; ++ new DLibPro(lib::triangulate,string("TRIANGULATE"),4,triangulateKey); ++ ++ const string qhullKey[]={"BOUNDS", "CONNECTIVITY", "DELAUNAY", "SPHERE", "VDIAGRAM" ,"VNORMALS", "VVERTICES", KLISTEND}; ++ new DLibPro(lib::qhull,string("QHULL"),8,qhullKey); ++ ++ const string sph_scatKey[]={"BOUNDS", "BOUT", "GOUT", "GS", "NLON", "NLAT", KLISTEND}; ++ new DLibFun(lib::sph_scat_fun,string("SPH_SCAT"),3,sph_scatKey); ++ ++ const string grid_inputKey[]={"SPHERE", "POLAR", "DEGREES", "DUPLICATES", "EPSILON", "EXCLUDE", KLISTEND}; ++ new DLibPro(lib::grid_input,string("GRID_INPUT"),6,grid_inputKey); ++ ++ const string qgrid3Key[]={"DELTA", "DIMENSION", "MISSING", "START", KLISTEND}; ++ new DLibFun(lib::qgrid3_fun,string("QGRID3"),5,qgrid3Key); ++#endif + + const string trigridKey[]={"MAX_VALUE","MISSING","NX","NY","MAP", + KLISTEND}; +@@ -255,8 +271,9 @@ const string tvrdKey[]={"CHANNEL","ORDER","TRUE","WORDS",KLISTEND}; new DLibFun(lib::tvrd,string("TVRD"),5,tvrdKey); @@ -8076,11 +28199,69 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/libinit_jmg.cpp g const string widget_baseKey[] = {"ALIGN_BOTTOM","ALIGN_CENTER","ALIGN_LEFT","ALIGN_RIGHT","ALIGN_TOP","MBAR","MODAL","BASE_ALIGN_BOTTOM","BASE_ALIGN_CENTER","BASE_ALIGN_LEFT","BASE_ALIGN_RIGHT","BASE_ALIGN_TOP","COLUMN","ROW","CONTEXT_EVENTS","CONTEXT_MENU","EVENT_FUNC","EVENT_PRO","EXCLUSIVE","NONEXCLUSIVE","FLOATING","FRAME","FUNC_GET_VALUE","GRID_LAYOUT","GROUP_LEADER","KBRD_FOCUS_EVENTS","KILL_NOTIFY","MAP","NO_COPY","NOTIFY_REALIZE","PRO_SET_VALUE","SCR_XSIZE","SCR_YSIZE","SCROLL","SENSITIVE","SPACE","TITLE","TLB_FRAME_ATTR","TLB_ICONIFY_EVENTS","TLB_KILL_REQUEST_EVENTS","TLB_MOVE_EVENTS","TLB_SIZE_EVENTS","TOOLBAR","TRACKING_EVENTS","UNITS","UNAME","UVALUE","XOFFSET","XPAD","XSIZE","X_SCROLL_SIZE","YOFFSET","YPAD","YSIZE","Y_SCROLL_SIZE","DISPLAY_NAME","RESOURCE_NAME","RNAME_MBAR",KLISTEND}; new DLibFun(lib::widget_base,string("WIDGET_BASE"),1,widget_baseKey); +@@ -306,5 +323,3 @@ + new DLibFun(lib::call_external, string("CALL_EXTERNAL"), -1, call_externalKey); + + } +- +- +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/magick_cl.cpp gdl/src/magick_cl.cpp +--- gdl-0.9.3/src/magick_cl.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/magick_cl.cpp 2013-03-21 14:04:04.340825348 -0600 +@@ -55,30 +55,7 @@ + unsigned int gValid[40]; + unsigned int gCount=0; + +- string GDLutos(unsigned int i) +- { +- int mema=3; +- char *n=new char(mema); +- while (snprintf(n, sizeof n, "%u", i) >= sizeof n) +- { delete n;mema++; n=new char(mema); } +- string s=n; +- delete n; +- return s; +- } +- + +- string GDLitos(int i) +- { +- int mema=3; +- char *n=new char(mema); +- while (snprintf(n, sizeof n, "%d", i) >= sizeof n) +- { delete n;mema++; n=new char(mema); } +- string s=n; +- delete n; +- return s; +- } +- +- + void magick_setup() + { + int i; +@@ -564,7 +541,7 @@ + else + { + string s="MAGICK_READ: RGB order type not supported ("; +- s+=GDLutos(rgb); ++ s+=i2s(rgb); + s+="), using BGR ordering."; + Message(s); + map="BGR"; +@@ -659,7 +636,7 @@ + else + { + string s="MAGICK_WRITE: RGB order type not supported ("; +- s+=GDLutos(rgb); ++ s+=i2s(rgb); + s+="), using BGR ordering."; + Message(s); + map="BGR"; Only in gdl-0.9.3/src: .#Makefile.am.1.64 Only in gdl-0.9.3/src: Makefile.in diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_fun_ac.cpp gdl/src/math_fun_ac.cpp --- gdl-0.9.3/src/math_fun_ac.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/math_fun_ac.cpp 2013-02-25 17:04:25.080179130 -0700 ++++ gdl/src/math_fun_ac.cpp 2013-03-21 14:04:04.368825218 -0600 @@ -6,11 +6,6 @@ email : alaingdl@users.sourceforge.net @@ -8093,7 +28274,189 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_fun_ac.cpp g /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * -@@ -735,5 +730,144 @@ +@@ -52,6 +47,7 @@ + + */ + ++ + #define GM_EPS 1.0e-6 + #define GM_ITER 50 + #define GM_TINY 1.0e-18 +@@ -67,7 +63,7 @@ + throw GDLException(e->CallingNode(), "Variable is undefined: "+e->GetParString(0)); \ + \ + DType t0 = e->GetParDefined(0)->Type(); \ +- //if (t0 == GDL_COMPLEX || t0 == GDL_COMPLEXDBL) \ ++ //if (t0 == GDL_COMPLEX || t0 == GDL_COMPLEXDBL) \ + // e->Throw("Complex not implemented (GSL limitation). "); + + #define AC_2P1() \ +@@ -81,7 +77,7 @@ + p1 = new DIntGDL(1, BaseGDL::NOZERO); \ + (*p1)[0]=0; \ + nElp1=1; \ +- t1 = GDL_INT; \ ++ t1 = GDL_INT; \ + p1_float = new DFloatGDL(1, BaseGDL::NOZERO); \ + (*p1_float)[0]=0.000; \ + } \ +@@ -97,25 +93,25 @@ + \ + // throw GDLException(e->CallingNode(), "Variable is undefined: "+e->GetParString(1)); \ + \ +-// DType t1 = e->GetParDefined(1)->Type(); \ +- // if (t1 == GDL_COMPLEX || t1 == GDL_COMPLEXDBL) \ ++ // DType t1 = e->GetParDefined(1)->Type(); \ ++ // if (t1 == GDL_COMPLEX || t1 == GDL_COMPLEXDBL) \ + // e->Throw("Complex not implemented (GSL limitation). "); + +-#define GM_DF2() \ +- \ +- DDoubleGDL* res; \ +- if (nElp0 == 1 && nElp1 == 1) \ +- res = new DDoubleGDL(1, BaseGDL::NOZERO); \ +- else if (nElp0 > 1 && nElp1 == 1) \ +- res = new DDoubleGDL(p0->Dim(), BaseGDL::NOZERO); \ +- else if (nElp0 == 1 && nElp1 > 1) \ +- res = new DDoubleGDL(p1->Dim(), BaseGDL::NOZERO); \ +- else if (nElp0 <= nElp1) \ +- res = new DDoubleGDL(p0->Dim(), BaseGDL::NOZERO); \ +- else \ +- res = new DDoubleGDL(p1->Dim(), BaseGDL::NOZERO); \ +- \ +- SizeT nElp = res->N_Elements(); \ ++#define GM_DF2() \ ++ \ ++ DDoubleGDL* res; \ ++ if (nElp0 == 1 && nElp1 == 1) \ ++ res = new DDoubleGDL(1, BaseGDL::NOZERO); \ ++ else if (nElp0 > 1 && nElp1 == 1) \ ++ res = new DDoubleGDL(p0->Dim(), BaseGDL::NOZERO); \ ++ else if (nElp0 == 1 && nElp1 > 1) \ ++ res = new DDoubleGDL(p1->Dim(), BaseGDL::NOZERO); \ ++ else if (nElp0 <= nElp1) \ ++ res = new DDoubleGDL(p0->Dim(), BaseGDL::NOZERO); \ ++ else \ ++ res = new DDoubleGDL(p1->Dim(), BaseGDL::NOZERO); \ ++ \ ++ SizeT nElp = res->N_Elements(); \ + + #define GM_CV0() \ + static DInt doubleKWIx = e->KeywordIx("DOUBLE"); \ +@@ -133,20 +129,20 @@ + else \ + return res; + +-#define GM_CC1() \ +- static DInt coefKWIx = e->KeywordIx("ITER"); \ +- if(e->KeywordPresent(coefKWIx)) \ +- { \ ++#define GM_CC1() \ ++ static DInt coefKWIx = e->KeywordIx("ITER"); \ ++ if(e->KeywordPresent(coefKWIx)) \ ++ { \ + cout << "ITER keyword not used, always return -1)" << endl; \ +- e->SetKW( coefKWIx, new DLongGDL( -1)); \ ++ e->SetKW( coefKWIx, new DLongGDL( -1)); \ + } + +-#define AC_HELP() \ +- if (e->KeywordSet("HELP")) { \ ++#define AC_HELP() \ ++ if (e->KeywordSet("HELP")) { \ + string inline_help[]={ \ + "Usage: res="+e->GetProName()+"(x, [n,] double=double)", \ + " -- x is a number or an array", \ +- " -- n is a number or an array (if missing, set to 0)", \ ++ " -- n is a number or an array (if missing, set to 0)", \ + " If x and n dimensions differ, reasonnable rules applied"}; \ + int size_of_s = sizeof(inline_help) / sizeof(inline_help[0]); \ + e->Help(inline_help, size_of_s); \ +@@ -158,12 +154,16 @@ + #include + + #ifdef _MSC_VER +-#define isfinite _finite ++#define isfinite _finite + #define isinf !_finite + #endif + + using namespace std; + ++#if defined(USE_EIGEN) ++using namespace Eigen; ++#endif ++ + namespace lib { + + BaseGDL* beseli_fun(EnvT* e) +@@ -177,8 +177,8 @@ + + // GSL Limitation for X : must be lower than ~708 + for (count = 0;count 708.) +- e->Throw("Value of X is out of allowed range."); ++ if ((*p0)[count] > 708.) ++ e->Throw("Value of X is out of allowed range."); + + // we need to check if N values (array) are Integer or not + int test=0; +@@ -520,10 +520,10 @@ + + // we only issue a message + if (nElpXpos != nElpYpos) { +- cout << "SPL_INIT (warning): X and Y arrays do not have same lengths !" << endl; +- // all next computations to be done on MIN(nElpXpos,nElpYpos) (except NaN/Inf checks) +- if (nElpXpos > nElpYpos) +- nElpXpos=nElpYpos; ++ cout << "SPL_INIT (warning): X and Y arrays do not have same lengths !" << endl; ++ // all next computations to be done on MIN(nElpXpos,nElpYpos) (except NaN/Inf checks) ++ if (nElpXpos > nElpYpos) ++ nElpXpos=nElpYpos; + } + + // creating result array +@@ -580,10 +580,10 @@ + DDoubleGDL* YP0; + + if(Yderiv0 !=NULL && !isinf((*(YP0=e->GetKWAs(e->KeywordIx("YP0"))))[0] )){ +- // first derivative at the point X0 is defined and different to Inf ++ // first derivative at the point X0 is defined and different to Inf + (*res)[0]=-0.5; + (*U)[0] = ( 3. / ((*Xpos)[1]-(*Xpos)[0])) * (((*Ypos)[1]-(*Ypos)[0]) / +- ((*Xpos)[1]-(*Xpos)[0]) - (*YP0)[0] ); ++ ((*Xpos)[1]-(*Xpos)[0]) - (*YP0)[0] ); + + }else{ + // YP0 is omitted or equal to Inf +@@ -613,7 +613,7 @@ + DDoubleGDL* YPN; + + if(YderivN !=NULL && !isinf((*(YPN=e->GetKWAs(e->KeywordIx("YPN_1"))))[0] )){ +- // first derivative at the point XN-1 is defined and different to Inf ++ // first derivative at the point XN-1 is defined and different to Inf + (*res)[nElpXpos-1] =0.; + qn=0.5; + +@@ -621,7 +621,7 @@ + (*U)[nElpXpos-1]= (3./dx)*((*YPN)[0]-((*Ypos)[nElpXpos-1]-(*Ypos)[nElpXpos-2])/dx); + + }else{ +- // YPN_1 is omitted or equal to Inf ++ // YPN_1 is omitted or equal to Inf + qn=0.; + (*U)[nElpXpos-1]=0.; + } +@@ -629,7 +629,7 @@ + (*res)[nElpXpos-1] =((*U)[nElpXpos-1]-qn*(*U)[nElpXpos-2])/(qn*(*res)[nElpXpos-2]+ 1.); + + for (count = nElpXpos-2; count != -1; --count){ +- (*res)[count] =(*res)[count]*(*res)[count+1]+(*U)[count]; ++ (*res)[count] =(*res)[count]*(*res)[count+1]+(*U)[count]; + } + + GM_CV0(); +@@ -735,5 +735,411 @@ return NULL; } @@ -8102,124 +28465,391 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_fun_ac.cpp g + // (succesfully tested with Eigen 3.2 and gcc 4.1, + // as fast as IDL 8 on M#transpose(M), with M=[400,60000] matrix multiply.) +#if defined(USE_EIGEN) -+ -+ BaseGDL* matmul_fun( EnvT* e){ + -+ if (e->KeywordSet("AVAILABLE")) return new DLongGDL(1); -+ -+ if (e->GetParDefined(0)->Type() == GDL_STRING) -+ e->Throw( "Array Type cannot be STRING here: "+ e->GetParString(0)); -+ if (e->GetParDefined(1)->Type() == GDL_STRING) -+ e->Throw( "Array Type cannot be STRING here: "+ e->GetParString(1)); -+ if (e->GetParDefined(0)->Type() == GDL_STRUCT) -+ e->Throw( "Array Type cannot be a STRUCTURE here: "+ e->GetParString(0)); -+ if (e->GetParDefined(1)->Type() == GDL_STRUCT) -+ e->Throw( "Array Type cannot be STRUCTURE here: "+ e->GetParString(1)); -+ -+ int debug=0; -+ if (e->KeywordSet("DEBUG") || (debug == 1)) { -+ cout << "Rank Matrix A : "<< e->GetParDefined(0)->Rank() << endl; -+ cout << "Dim Matrix A : " << e->GetParDefined(0)->Dim() << endl; -+ cout << "Rank Matrix B : "<< e->GetParDefined(1)->Rank() << endl; -+ cout << "Dim Matrix B : " << e->GetParDefined(1)->Dim() << endl; -+ } ++ BaseGDL* matmul_fun(EnvT* e) ++ { ++ static int avIx = e->KeywordIx("AVAILABLE"); ++ if (e->KeywordSet(avIx)) return new DLongGDL(1); + -+ if (e->GetParDefined(0)->Rank() > 2) -+ e->Throw( "Array must have 1 or 2 dimensions: "+ e->GetParString(0)); -+ if (e->GetParDefined(1)->Rank() > 2) -+ e->Throw( "Array must have 1 or 2 dimensions: "+ e->GetParString(1)); -+ -+ if ((e->GetParDefined(0)->Type() == GDL_COMPLEX) || (e->GetParDefined(0)->Type() == GDL_COMPLEXDBL)) -+ e->Throw( "We are not ready here for COMPLEX type, plese use # operator: "+ e->GetParString(0)); -+ if ((e->GetParDefined(1)->Type() == GDL_COMPLEX) || (e->GetParDefined(1)->Type() == GDL_COMPLEXDBL)) -+ e->Throw( "We are not ready here for COMPLEX type, plese use # operator: "+ e->GetParString(1)); ++ BaseGDL* par0 = e->GetParDefined(0); ++ BaseGDL* par1 = e->GetParDefined(1); + -+ DDoubleGDL* p0 = e->GetParAs(0); -+ DDoubleGDL* p1 = e->GetParAs(1); -+ -+ long NbCol0, NbRow0, NbCol1, NbRow1, tmp_permut; ++ DType type0 = par0->Type(); ++ if (!NumericType(type0)) ++ e->Throw("Array type cannot be " + par0->TypeStr() + " here: " + e->GetParString(0)); ++ DType type1 = par1->Type(); ++ if (!NumericType(type1)) ++ e->Throw("Array type cannot be " + par1->TypeStr() + " here: " + e->GetParString(1)); + -+ if (e->GetParDefined(0)->Rank() == 2) { -+ NbCol0=p0->Dim(0); -+ NbRow0=p0->Dim(1); -+ } else { -+ NbCol0=p0->Dim(0); -+ NbRow0=1; -+ } -+ if (e->KeywordSet("ATRANSPOSE")) { -+ tmp_permut=NbCol0; -+ NbCol0=NbRow0; -+ NbRow0=tmp_permut; -+ } -+ // cout << "NbCol0, NbRow0 : "<< NbCol0 << " " << NbRow0 << endl; -+ MatrixXd m0 (NbCol0,NbRow0); ++ // const int debug = 0; ++ // static int debugIx = e->KeywordIx("DEBUG"); ++ // if (e->KeywordSet(debugIx) || debug == 1) ++ // { ++ // cout << "Rank Matrix A : " << par0->Rank() << endl; ++ // cout << "Dim Matrix A : " << par0->Dim() << endl; ++ // cout << "Rank Matrix B : " << par1->Rank() << endl; ++ // cout << "Dim Matrix B : " << par1->Dim() << endl; ++ // } + -+ if (e->KeywordSet("ATRANSPOSE")) { -+ for (SizeT j=0; jKeywordIx("ATRANSPOSE"); ++ static int btIx = e->KeywordIx("BTRANSPOSE"); ++ bool at = e->KeywordSet(atIx); ++ bool bt = e->KeywordSet(btIx); + -+ // cout << m0 << endl; ++ long NbCol0, NbRow0, NbCol1, NbRow1;//, NbCol2, NbRow2; ++ SizeT rank0 = par0->Rank(); ++ if (rank0 == 2) ++ { ++ NbCol0 = par0->Dim(0); ++ NbRow0 = par0->Dim(1); ++ } ++ else if (rank0 > 2) ++ { ++ e->Throw("Array must have 1 or 2 dimensions: " + e->GetParString(0)); ++ } ++ else ++ { ++ NbCol0 = par0->Dim(0); ++ NbRow0 = 1; ++ } ++ ++ SizeT rank1 = par1->Rank(); ++ if (rank1 == 2) ++ { ++ NbCol1 = par1->Dim(0); ++ NbRow1 = par1->Dim(1); ++ } ++ else if (rank1 > 2) ++ { ++ e->Throw("Array must have 1 or 2 dimensions: " + e->GetParString(1)); ++ } ++ else ++ { ++ if (rank0 == 1 && !at && !bt) ++ { ++ NbCol1 = 1; ++ NbRow1 = par1->Dim(0); ++ } else ++ { ++ NbCol1 = par1->Dim(0); ++ NbRow1 = 1; ++ } ++ } ++ ++ if ( (type0 == GDL_COMPLEXDBL || type1 == GDL_COMPLEXDBL) || ++ (type0 == GDL_COMPLEX && type1 == GDL_DOUBLE ) || ++ (type0 == GDL_DOUBLE && type1 == GDL_COMPLEX ) ) ++ { ++ DComplexDblGDL* dcp0 = e->GetParAs (0); ++ DComplexDblGDL* dcp1 = e->GetParAs (1); ++ // Type = GDL_COMPLEXDBL; ++ // case GDL_COMPLEXDBL: ++ { //avoid CASE crosses ! ++ // MatrixXcd m0(NbCol0, NbRow0); ++ // memcpy(&m0(0, 0), &(*dcp0)[0], NbCol0 * NbRow0 * sizeof ((*dcp0)[0])); ++ //fastest: directly pass adresses in Map structure of good type! ++ Map m0(&(*dcp0)[0], NbCol0, NbRow0); ++ // MatrixXcd m1(NbCol1, NbRow1); ++ // memcpy(&m1(0, 0), &(*dcp1)[0], NbCol1 * NbRow1 * sizeof ((*dcp1)[0])); ++ Map m1(&(*dcp1)[0], NbCol1, NbRow1); + -+ if (e->GetParDefined(1)->Rank() == 2) { -+ NbCol1=p1->Dim(0); -+ NbRow1=p1->Dim(1); -+ } else { -+ NbCol1=p1->Dim(0); -+ NbRow1=1; -+ } -+ if (e->KeywordSet("BTRANSPOSE")) { -+ tmp_permut=NbCol1; -+ NbCol1=NbRow1; -+ NbRow1=tmp_permut; -+ } ++ if (at && bt) ++ { ++ if( /*(at && bt) &&*/ (NbCol0 != NbRow1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbRow0 ; ++ long& NbRow2 = NbCol1 ; ++ dimension dim(NbCol2, NbRow2); ++ ++ DComplexDblGDL* res = new DComplexDblGDL(dim, BaseGDL::NOZERO); ++ // no guarding necessary: eigen only throws on memory allocation + -+ MatrixXd m1 (NbCol1,NbRow1); ++ //MatrixXcd m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0.transpose() * m1.transpose(); ++ return res; ++ } else if (bt) ++ { ++ if( /*(!at && bt) &&*/ (NbRow0 != NbRow1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbCol0; ++ long& NbRow2 = NbCol1; ++ dimension dim(NbCol2, NbRow2); + -+ if (e->KeywordSet("BTRANSPOSE")) { -+ for (SizeT j=0; jThrow( "Incompatible dimensions [m,n]#[n,o] expected "); ++ DComplexDblGDL* res = new DComplexDblGDL(dim, BaseGDL::NOZERO); ++ //MatrixXcd m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0 * m1.transpose(); ++ return res; ++ } else if (at) ++ { ++ if( /*(at && !bt) &&*/ (NbCol0 != NbCol1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbRow0; ++ long& NbRow2 = NbRow1; ++ dimension dim(NbCol2, NbRow2); + -+ if (e->KeywordSet("DEBUG") || (debug == 1)) { -+ cout << "NbCol0, NbRow0 : "<< NbCol0 << " " << NbRow0 << endl; -+ cout << "NbCol1, NbRow1 : "<< NbCol1 << " " << NbRow1 << endl; -+ //cout << m0 << endl; -+ } ++ DComplexDblGDL* res = new DComplexDblGDL(dim, BaseGDL::NOZERO); ++ //MatrixXcd m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0.transpose() * m1; ++ return res; ++ } else ++ { ++ if( /*(!at && !bt) &&*/ (NbRow0 != NbCol1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbCol0; ++ long& NbRow2 = NbRow1; ++ dimension dim(NbCol2, NbRow2); + -+ MatrixXd tmp_res (NbCol0,NbRow1); -+ tmp_res=m0*m1; ++ DComplexDblGDL* res = new DComplexDblGDL(dim, BaseGDL::NOZERO); ++ //MatrixXcd m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0*m1; ++ return res; ++ } + -+ dimension dim(NbCol0,NbRow1); ++ // memcpy(&(*res)[0], &m2(0, 0), NbCol2 * NbRow2 * sizeof (m2(0,0))); ++ } ++ } else if (type0 == GDL_COMPLEX || type1 == GDL_COMPLEX) ++ { ++ DComplexGDL *cp0 = e->GetParAs (0); ++ DComplexGDL *cp1 = e->GetParAs (1); ++ // Type = GDL_COMPLEX; ++ // case GDL_COMPLEX: ++ { ++ // MatrixXcf m0(NbCol0, NbRow0); ++ // memcpy(&m0(0, 0), &(*cp0)[0], NbCol0 * NbRow0 * sizeof ((*cp0)[0])); ++ Map m0(&(*cp0)[0], NbCol0, NbRow0); + -+ if ((e->GetParDefined(0)->Type() == GDL_DOUBLE) || (e->GetParDefined(1)->Type() == GDL_DOUBLE)) { -+ DDoubleGDL* res = new DDoubleGDL(dim, BaseGDL::NOZERO); -+ for (SizeT i=0; i m1(&(*cp1)[0], NbCol1, NbRow1); ++ ++ if (at && bt) ++ { ++ if( /*(at && bt) &&*/ (NbCol0 != NbRow1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbRow0; ++ long& NbRow2 = NbCol1; ++ dimension dim(NbCol2, NbRow2); ++ ++ DComplexGDL* res = new DComplexGDL(dim, BaseGDL::NOZERO); ++ // MatrixXcf m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0.transpose() * m1.transpose(); ++ return res; ++ } else if (bt) ++ { ++ if( /*(!at && bt) &&*/ (NbRow0 != NbRow1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbCol0; ++ long& NbRow2 = NbCol1; ++ dimension dim(NbCol2, NbRow2); ++ ++ DComplexGDL* res = new DComplexGDL(dim, BaseGDL::NOZERO); ++ // MatrixXcf m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0 * m1.transpose(); ++ return res; ++ } else if (at) ++ { ++ if( /*(at && !bt) &&*/ (NbCol0 != NbCol1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbRow0; ++ long& NbRow2 = NbRow1; ++ dimension dim(NbCol2, NbRow2); ++ ++ DComplexGDL* res = new DComplexGDL(dim, BaseGDL::NOZERO); ++ // MatrixXcf m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0.transpose() * m1; ++ return res; ++ } else ++ { ++ if( /*(!at && !bt) &&*/ (NbRow0 != NbCol1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbCol0; ++ long& NbRow2 = NbRow1; ++ dimension dim(NbCol2, NbRow2); ++ ++ DComplexGDL* res = new DComplexGDL(dim, BaseGDL::NOZERO); ++ // MatrixXcf m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0*m1; ++ return res; ++ } ++ // memcpy(&(*res)[0], &m2(0, 0), NbCol2 * NbRow2 * sizeof (m2(0,0))); ++ } ++ } else if (type0 == GDL_DOUBLE || type1 == GDL_DOUBLE) ++ { ++ DDoubleGDL* p0 = e->GetParAs (0); ++ DDoubleGDL* p1 = e->GetParAs (1); ++ // Type = GDL_DOUBLE; ++ // case GDL_DOUBLE: ++ { ++ // MatrixXd m0(NbCol0, NbRow0); ++ // memcpy(&m0(0,0),&(*p0)[0],NbCol0*NbRow0*sizeof((*p0)[0])); ++ Map m0(&(*p0)[0], NbCol0, NbRow0); ++ ++ // MatrixXd m1(NbCol1, NbRow1); ++ // memcpy(&m1(0,0),&(*p1)[0],NbCol1*NbRow1*sizeof((*p1)[0])); ++ Map m1(&(*p1)[0], NbCol1, NbRow1); ++ ++ if (at && bt) ++ { ++ if( /*(at && bt) &&*/ (NbCol0 != NbRow1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbRow0; ++ long& NbRow2 = NbCol1; ++ dimension dim(NbCol2, NbRow2); ++ ++ DDoubleGDL* res = new DDoubleGDL(dim, BaseGDL::NOZERO); ++ // MatrixXd m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0.transpose() * m1.transpose(); ++ return res; ++ } ++ else if (bt) { ++ if( /*(!at && bt) &&*/ (NbRow0 != NbRow1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbCol0; ++ long& NbRow2 = NbCol1; ++ dimension dim(NbCol2, NbRow2); ++ ++ DDoubleGDL* res = new DDoubleGDL(dim, BaseGDL::NOZERO); ++ // MatrixXd m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0 * m1.transpose(); ++ return res; ++ } ++ else if (at) { ++ if( /*(at && !bt) &&*/ (NbCol0 != NbCol1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbRow0; ++ long& NbRow2 = NbRow1; ++ dimension dim(NbCol2, NbRow2); ++ ++ DDoubleGDL* res = new DDoubleGDL(dim, BaseGDL::NOZERO); ++ // MatrixXd m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0.transpose() * m1; ++ return res; ++ } ++ else { ++ if( /*(!at && !bt) &&*/ (NbRow0 != NbCol1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbCol0; ++ long& NbRow2 = NbRow1; ++ dimension dim(NbCol2, NbRow2); ++ ++ DDoubleGDL* res = new DDoubleGDL(dim, BaseGDL::NOZERO); ++ // MatrixXd m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0*m1; ++ return res; ++ } ++ } ++ } else //all other cases: FLOAT! ++ { ++ DFloatGDL* pf0 = e->GetParAs (0); ++ DFloatGDL* pf1 = e->GetParAs (1); ++ // Type = GDL_FLOAT; ++ // case GDL_FLOAT: ++ { ++ Map m0(&(*pf0)[0], NbCol0, NbRow0); ++ Map m1(&(*pf1)[0], NbCol1, NbRow1); ++ if (at && bt) { ++ if( /*(at && bt) &&*/ (NbCol0 != NbRow1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbRow0; ++ long& NbRow2 = NbCol1; ++ dimension dim(NbCol2, NbRow2); ++ DFloatGDL* res = new DFloatGDL(dim, BaseGDL::NOZERO); ++ // MatrixXf m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0.transpose() * m1.transpose(); ++ return res; ++ } ++ else if (bt) { ++ if( /*(!at && bt) &&*/ (NbRow0 != NbRow1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbCol0; ++ long& NbRow2 = NbCol1; ++ dimension dim(NbCol2, NbRow2); ++ DFloatGDL* res = new DFloatGDL(dim, BaseGDL::NOZERO); ++ // MatrixXf m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0 * m1.transpose(); ++ return res; ++ } ++ else if (at) { ++ if( /*(at && !bt) &&*/ (NbCol0 != NbCol1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbRow0; ++ long& NbRow2 = NbRow1; ++ dimension dim(NbCol2, NbRow2); ++ DFloatGDL* res = new DFloatGDL(dim, BaseGDL::NOZERO); ++ // MatrixXf m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0.transpose() * m1; ++ return res; ++ } ++ else { ++ if( /*(!at && !bt) &&*/ (NbRow0 != NbCol1)) ++ { ++ e->Throw("Operands of matrix multiply have incompatible dimensions: " + e->GetParString(0) + ", " + e->GetParString(1) + "."); ++ } ++ long& NbCol2 = NbCol0; ++ long& NbRow2 = NbRow1; ++ dimension dim(NbCol2, NbRow2); ++ DFloatGDL* res = new DFloatGDL(dim, BaseGDL::NOZERO); ++ // MatrixXf m2(NbCol2, NbRow2); ++ Map m2(&(*res)[0], NbCol2, NbRow2); ++ m2.noalias() = m0*m1; ++ return res; ++ } ++ } ++ } + } ++ ++ ++ ++ ++ ++ ++#else // defined(USE_EIGEN) + -+#else + BaseGDL* matmul_fun( EnvT* e){ + + if (e->KeywordSet("AVAILABLE")) { @@ -8234,37 +28864,908 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_fun_ac.cpp g + return NULL; + } + -+#endif ++#endif // defined(USE_EIGEN) + } // namespace diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_fun_ac.hpp gdl/src/math_fun_ac.hpp --- gdl-0.9.3/src/math_fun_ac.hpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/math_fun_ac.hpp 2013-02-25 17:04:25.081179126 -0700 ++++ gdl/src/math_fun_ac.hpp 2013-03-21 14:04:04.368825218 -0600 @@ -18,6 +18,11 @@ #include "datatypes.hpp" #include "envt.hpp" +#if defined(USE_EIGEN) +#include -+using namespace Eigen; ++//using namespace Eigen; // never in header files! +#endif + namespace lib { BaseGDL* beseli_fun( EnvT* e); -@@ -31,6 +36,7 @@ +@@ -31,6 +36,8 @@ BaseGDL* sobel_fun( EnvT* e); BaseGDL* roberts_fun( EnvT* e); BaseGDL* prewitt_fun( EnvT* e); + BaseGDL* matmul_fun( EnvT* e); ++ BaseGDL* matmulold_fun( EnvT* e); } // namespace +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_fun.cpp gdl/src/math_fun.cpp +--- gdl-0.9.3/src/math_fun.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/math_fun.cpp 2013-03-21 14:04:04.351825297 -0600 +@@ -223,16 +223,26 @@ + T* p0C = static_cast( p0); + T* res = new T( p0C->Dim(), BaseGDL::NOZERO); + SizeT nEl = p0->N_Elements(); ++// eigen is not faster here ++// #ifdef USE_EIGEN ++// ++// Eigen::Map ,Eigen::Aligned> m1(&(*p0C)[0], nEl); ++// Eigen::Map ,Eigen::Aligned> m2(&(*res)[0], nEl); ++// m2 = m1.sin(); ++// return res; ++// #else + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i((*p0C)[ i])); + } +@@ -406,7 +416,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i( p0); + T* res = new T( p0C->Dim(), BaseGDL::NOZERO); + SizeT nEl = p0->N_Elements(); ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mP0C(&(*p0C)[0], nEl); ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mP0C.sqrt(); ++ return res; ++#else ++ + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma intel omp forthis +- for( int i=0; i +@@ -1095,16 +1115,23 @@ + { + T* p0C = static_cast( p0); + SizeT nEl = p0->N_Elements(); ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mP0C(&(*p0C)[0], nEl); ++ mP0C = mP0C.sqrt(); ++ return p0C; ++#else + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; iN_Elements() > 0); + ++ DType p0Type = p0->Type(); + if( isReference) + { +- if( p0->Type() == GDL_COMPLEX) ++ if( p0Type == GDL_COMPLEX) + return sqrt_fun_template< DComplexGDL>( p0); +- else if( p0->Type() == GDL_COMPLEXDBL) ++ else if( p0Type == GDL_COMPLEXDBL) + return sqrt_fun_template< DComplexDblGDL>( p0); +- else if( p0->Type() == GDL_DOUBLE) ++ else if( p0Type == GDL_DOUBLE) + return sqrt_fun_template< DDoubleGDL>( p0); +- else if( p0->Type() == GDL_FLOAT) ++ else if( p0Type == GDL_FLOAT) + return sqrt_fun_template< DFloatGDL>( p0); + } + else + { +- if( p0->Type() == GDL_COMPLEX) ++ if( p0Type == GDL_COMPLEX) + return sqrt_fun_template_grab< DComplexGDL>( p0); +- else if( p0->Type() == GDL_COMPLEXDBL) ++ else if( p0Type == GDL_COMPLEXDBL) + return sqrt_fun_template_grab< DComplexDblGDL>( p0); +- else if( p0->Type() == GDL_DOUBLE) ++ else if( p0Type == GDL_DOUBLE) + return sqrt_fun_template_grab< DDoubleGDL>( p0); +- else if( p0->Type() == GDL_FLOAT) ++ else if( p0Type == GDL_FLOAT) + return sqrt_fun_template_grab< DFloatGDL>( p0); + } +- { +- DFloatGDL* res = static_cast +- (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); +- SizeT nEl = p0->N_Elements(); ++ { ++ DFloatGDL* res = static_cast ++ (p0->Convert2( GDL_FLOAT, BaseGDL::COPY)); ++ SizeT nEl = p0->N_Elements(); ++#ifdef USE_EIGEN ++ ++ Eigen::Map ,Eigen::Aligned> mRes(&(*res)[0], nEl); ++ mRes = mRes.sqrt(); ++ return res; ++#else + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) +- { ++ { + #pragma omp for +- for( int i=0; i + BaseGDL* abs_fun_template( BaseGDL* p0) + { +@@ -1162,7 +1196,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i( round((*p0C)[ i])); + } +@@ -1293,7 +1327,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i( round((*p0C)[ i])); + } +@@ -1328,7 +1362,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; iN_Elements(); +- int count; ++ OMPInt count; + + TRACEOMP( __FILE__, __LINE__) + #pragma omp parallel if (nEx >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEx)) +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_fun_jmg.cpp gdl/src/math_fun_jmg.cpp +--- gdl-0.9.3/src/math_fun_jmg.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/math_fun_jmg.cpp 2013-03-21 14:04:04.371825204 -0600 +@@ -733,7 +733,45 @@ + } + } + ++// see http://www.geom.umn.edu/software/qhull/. Used also with plplot. ++#ifdef PL_HAVE_QHULL ++ void triangulate ( EnvT* e) ++ { ++ DDoubleGDL *yVal, *xVal; ++ int npts; ++ SizeT nParam=e->NParam(); ++ if( nParam < 3) ++ { ++ e->Throw("Incorrect number of arguments."); ++ } ++ yVal = e->GetParAs< DDoubleGDL > (0); ++ if (yVal->Rank() == 0) e->Throw("Expression must be an array in this context: " + e->GetParString(0)); ++ npts=yVal->N_Elements(); ++ xVal = e->GetParAs< DDoubleGDL > (1); ++ if (xVal->Rank() == 0) e->Throw("Expression must be an array in this context: " + e->GetParString(1)); ++ if (xVal->N_Elements()!=npts) e->Throw("X & Y arrays must have same number of points."); ++ e->Throw("Writing in progress."); ++ } ++ void qhull ( EnvT* e) ++ { ++ e->Throw("Writing in progress."); ++ } ++ ++ void grid_input (EnvT* e) ++ { ++ e->Throw("Writing in progress."); ++ } ++ ++ BaseGDL* qgrid3_fun ( EnvT* e) ++ { ++ e->Throw("Writing in progress."); ++ } ++ BaseGDL* sph_scat_fun ( EnvT* e) ++ { ++ e->Throw("Writing in progress."); ++ } + ++#endif + BaseGDL* trigrid_fun( EnvT* e) + { + // Compute plane parameters A,B,C given 3 points on plane. +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_fun_jmg.hpp gdl/src/math_fun_jmg.hpp +--- gdl-0.9.3/src/math_fun_jmg.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/math_fun_jmg.hpp 2013-03-21 14:04:04.372825200 -0600 +@@ -56,6 +56,13 @@ + BaseGDL* finite_fun( EnvT* e); + BaseGDL* check_math_fun( EnvT* e); + BaseGDL* radon_fun( EnvT* e); ++#ifdef PL_HAVE_QHULL ++ void triangulate( EnvT* e); ++ void qhull ( EnvT* e); ++ void grid_input (EnvT* e); ++ BaseGDL* qgrid3_fun ( EnvT* e); ++ BaseGDL* sph_scat_fun ( EnvT* e); ++#endif + BaseGDL* trigrid_fun( EnvT* e); + BaseGDL* poly_2d_fun( EnvT* e); + BaseGDL* rk4jmg_fun( EnvT* e); +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/math_utl.hpp gdl/src/math_utl.hpp +--- gdl-0.9.3/src/math_utl.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/math_utl.hpp 2013-03-21 14:04:04.378825172 -0600 +@@ -73,6 +73,12 @@ + #define COMPLEX2 GDL_COMPLEX + #endif + ++#ifdef _MSC_VER ++# define isinf !_finite ++# define isfinite _finite ++# define isnan _isnan ++#endif ++ + } // namespace + + #endif +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/ncdf_cl.cpp gdl/src/ncdf_cl.cpp +--- gdl-0.9.3/src/ncdf_cl.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/ncdf_cl.cpp 2013-03-21 14:04:04.387825130 -0600 +@@ -260,17 +260,8 @@ + else + { + /*unknown error*/ +- int mema=3; +- char *n=new char(mema); +- while (snprintf(n, sizeof n, "%d", status) >= sizeof n) +- { delete n;mema++; n=new char(mema); } +- + error+=nc_strerror(status); +- error+=" (NC_ERROR="; +- error+=n; +- delete n; +- error+=")"; +- ++ error+=" (NC_ERROR="+i2s(status)+")"; + } + + e->Throw(error); diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/ncdf_var_cl.cpp gdl/src/ncdf_var_cl.cpp --- gdl-0.9.3/src/ncdf_var_cl.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/ncdf_var_cl.cpp 2013-02-25 17:04:25.157178816 -0700 -@@ -962,7 +962,7 @@ ++++ gdl/src/ncdf_var_cl.cpp 2013-03-21 14:04:04.395825094 -0600 +@@ -57,27 +57,10 @@ + + void exceed_message(const char * name,int index, int set) + { +- int mema=3; + string mess; + mess=name; +- mess+="Limit exceeded on index "; +- char * n=new char(mema); +- while (snprintf(n, sizeof n, "%d", index) >= sizeof n) +- { delete n; mema++; n=new char(mema); +- } +- mess+=n; +- delete n; +- +- mess+=", setting to "; +- mema=3; +- n=new char(mema); +- while (snprintf(n, sizeof n, "%d", set) >= sizeof n) +- { +- delete n;mema++; n=new char(mema); +- } +- mess+=n; +- delete n; +- mess+="."; ++ mess+="Limit exceeded on index "+i2s(index); ++ mess+=", setting to "+i2s(set)+"."; + Message(mess); + + } +@@ -87,28 +70,14 @@ + int mema=3; + string mess; + mess=name; +- mess+="Value of index"; +- char * n=new char(mema); +- while (snprintf(n, sizeof n, "%d", index) >= sizeof n) +- { delete n; mema++; n=new char(mema); +- } +- mess+=n; +- delete n; ++ mess+="Value of index "+i2s(index); + if(set > 0) + mess+=" is negative or zero, setting to "; + else if(set == 0) + mess+=" is negative , setting to "; + else + mess+=" INTERNAL ERROR NCDF_VAR_CL.CPP negzero_message"; +- +- mema=3; +- n=new char(mema); +- while (snprintf(n, sizeof n, "%d", set) >= sizeof n) +- { +- delete n;mema++; n=new char(mema); +- } +- mess+=n; +- delete n; ++ mess+=i2s(set); + mess+="."; + Message(mess); + +@@ -660,22 +629,9 @@ + int mema=3; + string mess; + mess = "NCDF_VARGET: Requested read is larget than data in dimension "; +- char * n=new char(mema); +- while (snprintf(n, sizeof n, "%d", i) >= sizeof n) +- { +- delete n; mema++; n=new char(mema); +- } +- mess+=n; +- delete n; ++ mess+=i2s(i); + mess+=". Reducing COUNT to "; +- mema=3; +- n=new char[3]; +- while (snprintf(n, sizeof n, "%d", cou[trans[i]]) >= sizeof n) +- { +- delete n; mema++; n=new char(mema); +- } +- mess+=n; +- delete n; ++ mess+=i2s(cou[trans[i]]); + mess+="."; + Message(mess); + } +@@ -962,7 +918,7 @@ } } @@ -8286,6 +29787,125 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/new.cpp gdl/src/n } - Only in gdl-0.9.3/src: .#objects.cpp.1.22 +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/ofmt.cpp gdl/src/ofmt.cpp +--- gdl-0.9.3/src/ofmt.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/ofmt.cpp 2013-03-21 14:04:04.409825029 -0600 +@@ -675,8 +675,11 @@ + (*os) << oct << setw(w) << setfill(f) << (*this)[ i]; + else if ( oMode == BIN) + for( SizeT i=offs; i)i, w); ++#endif + else if ( oMode == HEX) + for( SizeT i=offs; i 32) +-// (*os) << binstr((std::bitset<32>)i >> 32, w - 32); +-// (*os) << binstr((std::bitset<32>)i, w <= 32 ? w : 32); +- if (w > 32) (*os) << binstr((*this)[ i] >> 32, w - 32); ++#ifdef _MSC_VER ++ if (w > 32) ++ (*os) << binstr((int)(*this)[ i] >> 32, w - 32); ++ (*os) << binstr((int)(*this)[ i], w <= 32 ? w : 32); ++#else ++ if (w > 32) ++ (*os) << binstr((*this)[ i] >> 32, w - 32); + (*os) << binstr((*this)[ i], w <= 32 ? w : 32); ++#endif + } + else if ( oMode == HEX) + for( SizeT i=offs; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*left)[i] == s); + } } + else if( left->StrictScalar(s)) +@@ -285,7 +285,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] == s); + } } + else if( rEl < nEl) +@@ -295,7 +295,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] == (*left)[i]); + } } + else // ( rEl >= nEl) +@@ -310,7 +310,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] == (*left)[i]); + } } + return res; +@@ -358,7 +358,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*left)[i] != s); + } } + else if( left->StrictScalar(s)) +@@ -373,7 +373,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] != s); + } } + else if( rEl < nEl) +@@ -383,7 +383,7 @@ + #pragma omp parallel if (rEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= rEl)) + { + #pragma omp for +- for( int i=0; i < rEl; ++i) ++ for( OMPInt i=0; i < rEl; ++i) + (*res)[i] = ((*right)[i] != (*left)[i]); + } } + else // ( rEl >= nEl) +@@ -398,7 +398,7 @@ + #pragma omp parallel if (nEl >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= nEl)) + { + #pragma omp for +- for( int i=0; i < nEl; ++i) ++ for( OMPInt i=0; i < nEl; ++i) + (*res)[i] = ((*right)[i] != (*left)[i]); + } } + return res; +@@ -410,6 +410,7 @@ + BaseGDL* _GDL_OBJECT_OverloadReportIllegalOperation( EnvUDT* e) + { + ThrowFromInternalUDSub( e, "Operation illegal with object reference types."); ++ return 0; + } + + // set up the _overload... subroutines for GDL_OBJECT diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_axis.cpp gdl/src/plotting_axis.cpp --- gdl-0.9.3/src/plotting_axis.cpp 2012-12-27 09:22:44.000000000 -0700 +++ gdl/src/plotting_axis.cpp 2013-02-25 17:04:30.966155138 -0700 @@ -8756,8 +30376,8 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_axis.cpp { diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_contour.cpp gdl/src/plotting_contour.cpp --- gdl-0.9.3/src/plotting_contour.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/plotting_contour.cpp 2013-02-25 17:04:30.991155036 -0700 -@@ -1,884 +1,696 @@ ++++ gdl/src/plotting_contour.cpp 2013-03-21 14:04:04.433824918 -0600 +@@ -1,884 +1,692 @@ -/*************************************************************************** - plotting.cpp - GDL routines for plotting - ------------------- @@ -9663,10 +31283,6 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_contour. +#include "plotting.hpp" +#include "math_utl.hpp" + -+#ifdef _MSC_VER -+# define isinf !_finite -+#endif -+ +#define LABELOFFSET 0.003 +#define LABELSPACING 0.25 + @@ -10340,8 +31956,8 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_contour. +} // namespace diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/src/plotting.cpp --- gdl-0.9.3/src/plotting.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/plotting.cpp 2013-02-25 17:04:30.959155167 -0700 -@@ -19,787 +19,1161 @@ ++++ gdl/src/plotting.cpp 2013-03-21 14:04:04.430824932 -0600 +@@ -19,787 +19,1160 @@ #include @@ -10361,8 +31977,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ #ifdef _MSC_VER -#define isfinite _finite -#define isnan _isnan -+# define isfinite _finite -+# define isnan _isnan ++#define snprintf _snprintf #endif -namespace lib { @@ -10431,7 +32046,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ + } } -+ template void gdlDoRangeExtrema(T* xVal, T* yVal, DDouble &min, DDouble &max, DDouble xmin, DDouble xmax, bool doMinMax=false, DDouble minVal=0, DDouble maxVal=0) ++ template void gdlDoRangeExtrema(T* xVal, T* yVal, DDouble &min, DDouble &max, DDouble xmin, DDouble xmax, bool doMinMax, DDouble minVal, DDouble maxVal) + { + DDouble valx, valy; + SizeT i,k; @@ -12089,7 +33704,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ // Map Stuff (xtype = 3) LPTYPE idata; XYTYPE odata; -@@ -807,27 +1181,29 @@ +@@ -807,27 +1180,29 @@ get_mapset(mapSet); DDouble xStart, xEnd; @@ -12131,7 +33746,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ // AC 070601 we use a buffer to use the fast ->line method // instead of the slow ->join one. -@@ -836,154 +1212,159 @@ +@@ -836,154 +1211,159 @@ // large among of data whitout duplicating all the arrays // trick 2/ when we have a NaN or and Inf, we realize the plot, then reset. @@ -12395,7 +34010,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ } } -@@ -996,543 +1377,1289 @@ +@@ -996,543 +1376,1289 @@ // explicit instantiation for SpDDouble template bool draw_polyline(EnvT*, GDLGStream*, Data_*, Data_*, DDouble, DDouble, bool, bool, bool, DLong, bool); @@ -12473,7 +34088,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ +#define GDL_PLPLOT_INDEX_WHITE 15 + void gdlSetGraphicsForegroundColorFromKw(EnvT *e, GDLGStream *a) + { -+ static uint colorindex=1; ++ static unsigned int colorindex=1; + static long value[GDL_PLPLOT_MAX_SIMPLE_COLORS]; + static int maxindex=2; + static bool notDone=1; @@ -12775,8 +34390,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ //LINESTYLE - void gkw_linestyle(EnvT *e, GDLGStream *a) + void gdlLineStyle(GDLGStream *a, DLong style) - { -- static DStructGDL* pStruct = SysVar::P(); ++ { + static PLINT mark1[]={75}; + static PLINT space1[]={1500}; + static PLINT mark2[]={1500}; @@ -12814,7 +34428,8 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ + } + + void gdlSetLineStyle(EnvT *e, GDLGStream *a) -+ { + { +- static DStructGDL* pStruct = SysVar::P(); + static DStructGDL* pStruct=SysVar::P(); DLong linestyle= - (*static_cast @@ -12885,11 +34500,11 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ + if ( linestyle<0 ) + { + linestyle=0; -+ } + } + if ( linestyle>5 ) + { + linestyle=5; - } ++ } + gdlLineStyle(a, linestyle); } @@ -13298,10 +34913,10 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ + } + return set; + } -+ -+ //STYLE - string StyleName=axis+"STYLE"; ++ //STYLE + + void gdlGetDesiredAxisStyle(EnvT *e, string axis, DLong &style) + { + DStructGDL* Struct; @@ -13314,7 +34929,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ + style= + (*static_cast(Struct->GetTag(styleTag, 0)))[0]; + } - ++ + string style_s=axis+"STYLE"; + e->AssureLongScalarKWIfPresent( style_s, style); } @@ -13503,9 +35118,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ + axisTickunitsVect=e->GetKWAs( axistickunitsIx ); + } + } - -- void gkw_axis_range(EnvT *e, string axis, DDouble &start, DDouble &end, -- DLong &ynozero) ++ + void gdlGetDesiredAxisTickv(EnvT* e, string axis, DDoubleGDL* axisTickvVect) + { + static DStructGDL* Struct=NULL; @@ -13530,7 +35143,9 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ + axisTickvVect=e->GetKWAs( axistickvIx ); + } + } -+ + +- void gkw_axis_range(EnvT *e, string axis, DDouble &start, DDouble &end, +- DLong &ynozero) + void gdlGetDesiredAxisTitle(EnvT *e, string axis, DString &title) { DStructGDL* Struct; @@ -13832,7 +35447,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ +#if (HAVE_PLPLOT_SLABELFUNC) + a->slabelfunc( NULL, NULL ); +#endif -+ } + } + else if (TickUnits->NBytes()>0) // /TICKUNITS=[several types of axes written below each other] + { + muaxdata.counter=0; @@ -13950,12 +35565,12 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting.cpp gdl/ + } + if (axis=="X") a->box(Opt.c_str(), 0.0, 0.0, "", 0.0, 0.0); + else if (axis=="Y") a->box("", 0.0, 0 , Opt.c_str(), 0.0, 0.0); - } ++ } + //reset charsize & thick + a->wid(1); + a->sizeChar(1.0); + } -+ ++ return 0; + } + bool gdlBox(EnvT *e, GDLGStream *a, DDouble xStart, DDouble xEnd, DDouble yStart, DDouble yEnd, bool xLog, bool yLog) + { @@ -14394,8 +36009,8 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_cursor.c x = new DDoubleGDL(tempx); diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_device.cpp gdl/src/plotting_device.cpp --- gdl-0.9.3/src/plotting_device.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/plotting_device.cpp 2013-02-25 17:04:31.007154971 -0700 -@@ -1,345 +1,404 @@ ++++ gdl/src/plotting_device.cpp 2013-03-21 14:04:04.436824904 -0600 +@@ -1,345 +1,416 @@ -/*************************************************************************** - plotting.cpp - GDL routines for plotting - ------------------- @@ -14930,7 +36545,19 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_device.c + e->Throw( "Current device does not support keyword CURSOR_STANDARD."); + } + } -+ // CURSOR_CROSSHAIR ++ // RETAIN ++ { ++ static int valIx = e->KeywordIx( "RETAIN"); ++ BaseGDL* res = e->GetKW( valIx); ++ if( res != NULL) ++ { ++ DLongGDL* val = e->GetKWAs( valIx); ++ bool success = actDevice->EnableBackingStore((*val)[0]); ++ if( !success) ++ e->Throw( "Current device does not support keyword RETAIN."); ++ } ++ } ++ // CURSOR_CROSSHAIR + { + static int valIx = e->KeywordIx( "CURSOR_CROSSHAIR"); + BaseGDL* res = e->GetKW( valIx); @@ -16015,7 +37642,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_misc.cpp } // namespace diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_oplot.cpp gdl/src/plotting_oplot.cpp --- gdl-0.9.3/src/plotting_oplot.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/plotting_oplot.cpp 2013-02-25 17:04:31.023154906 -0700 ++++ gdl/src/plotting_oplot.cpp 2013-03-21 14:04:04.443824872 -0600 @@ -39,8 +39,6 @@ // e->Throw( "Sorry, POLAR keyword not ready"); } @@ -16025,8 +37652,11 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_oplot.cp //test and transform eventually if POLAR and/or NSUM! if( nParam() == 1) { -@@ -128,23 +126,21 @@ +@@ -126,25 +124,24 @@ + } + } } ++ return 0; } - private: void old_body( EnvT* e, GDLGStream* actStream) // {{{ @@ -16054,7 +37684,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_oplot.cp if ((yStart == yEnd) || (xStart == xEnd)) { -@@ -157,9 +153,6 @@ +@@ -157,9 +154,6 @@ Message("OPLOT: !X.CRANGE ERROR, setting to [0,1]"); xStart = 0; //xVal->min(); xEnd = 1; //xVal->max(); @@ -16064,7 +37694,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_oplot.cp } //now we can setup minVal and maxVal to defaults: Start-End and overload if KW present -@@ -172,45 +165,39 @@ +@@ -172,45 +166,39 @@ e->AssureDoubleScalarKWIfPresent( "MIN_VALUE", minVal); e->AssureDoubleScalarKWIfPresent( "MAX_VALUE", maxVal); @@ -18353,7 +39983,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_surface. }; // surface_call class diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_windows.cpp gdl/src/plotting_windows.cpp --- gdl-0.9.3/src/plotting_windows.cpp 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/plotting_windows.cpp 2013-02-25 17:04:31.058154763 -0700 ++++ gdl/src/plotting_windows.cpp 2013-03-21 14:04:04.453824826 -0600 @@ -69,7 +69,7 @@ #ifdef HAVE_X DeviceX::DefaultXYSize(&xSize, &ySize); @@ -18363,7 +39993,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_windows. ySize = 512; #endif e->AssureLongScalarKWIfPresent( "XSIZE", xSize); -@@ -89,7 +89,17 @@ +@@ -89,7 +89,18 @@ bool success = actDevice->WOpen( wIx, title, xSize, ySize, xPos, yPos); if( !success) e->Throw( "Unable to create window."); @@ -18371,9 +40001,10 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_windows. + success = actDevice->CursorCrosshair(); + success = actDevice->UnsetFocus(); + bool doretain=true; ++ DLong retainType ; //=Graphics::getRetain(); ++// if (retainType=0) doretain=false; + if( e->KeywordPresent( 3)) // RETAIN + { -+ DLong retainType; + e->AssureLongScalarKWIfPresent( "RETAIN", retainType); + if (retainType=0) doretain=false; + } @@ -18382,7 +40013,7 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/plotting_windows. void wset( EnvT* e) { -@@ -113,7 +123,7 @@ +@@ -113,7 +124,7 @@ #ifdef HAVE_X DeviceX::DefaultXYSize(&xSize, &ySize); #else @@ -19070,6 +40701,102 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/dialog_pickfi if KEYWORD_SET(default_extension) then default_extension=STRING(default_extension[0]) ; Only in gdl-0.9.3/src/pro/dicom: Makefile.in +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/doc_library.pro gdl/src/pro/doc_library.pro +--- gdl-0.9.3/src/pro/doc_library.pro 1969-12-31 17:00:00.000000000 -0700 ++++ gdl/src/pro/doc_library.pro 2013-03-01 10:35:35.000000000 -0700 +@@ -0,0 +1,92 @@ ++;+ ++; NAME: ++; DOC_LIBRARY ++; ++; PURPOSE: ++; Extract and display documentation headers from a program or routine. ++; ++; CATEGORY: ++; Documentation ++; ++; CALLING SEQUENCE: ++; DOC_LIBRARY, procedure ++; ++; INPUTS: ++; procedure STRING The procedure to document. ++; ++; KEYWORD PARAMETERS: ++; /print Set to print the output to the default printer. ++; ++; SIDE EFFECTS: ++; A file is created in /tmp and deleted after use. ++; ++; RESTRICTIONS: ++; Only one documentation block per file is handled. ++; ++; EXAMPLE: ++; DOC_LIBRARY, 'doc_library' ++; ++; MODIFICATION HISTORY: ++; Original: 2013-March-28; SJT (see Feature Requests 3606434) ++; ++; LICENCE: ++; This code in under GNU GPL v2 or later ++; ++;- ++pro DOC_LIBRARY, proc, print = print, test=test ++ ++ON_ERROR, 2 ++ ++if (!version.os_family ne 'unix') then begin ++ print, "DOC_LIBRARY is currently only available for Unix like systems" ++ return ++endif ++ ++if (KEYWORD_SET(print)) then begin ++ less = FILE_WHICH(getenv('PATH'), 'lp') ++ if (less eq '') then less = FILE_WHICH(GETENV('PATH'), 'lpr') ++ if (less eq '') then begin ++ print, "Neither lp nor lpr was found" ++ return ++ endif ++endif else begin ++ less = FILE_WHICH(GETENV('PATH'), 'less') ++ if (less eq '') then less = FILE_WHICH(GETENV('PATH'), 'more') ++ if (less eq '') then begin ++ print, "Neither more nor less was found" ++ return ++ endif ++endelse ++ ++proc_path = FILE_WHICH(proc+'.pro', /include_current) ++if (proc_path eq '') then begin ++ print, proc, ' not found' ++ return ++endif ++ ++out_name = '/tmp/'+proc+'.txt' ++ ++OPENR, ipu, proc_path, /get ++dflag = 0b ++inln = '' ++ ++OPENW, isu, out_name, /get ++ ++while (~EOF(ipu)) do begin ++ READF, ipu, inln ++ inln = STRTRIM(inln, 2) ++ if (STRPOS(inln, ';+') eq 0) then dflag = 1b ++ if (STRPOS(inln, ';-') eq 0) then break ++ ;; ++ if dflag then printf, isu, STRMID(inln, 1) ++endwhile ++; ++FREE_LUN, isu, ipu ++; ++SPAWN, less+' '+out_name ++; ++FILE_DELETE, out_name ++; ++if KEYWORD_SET(test) then STOP ++; ++end Only in gdl-0.9.3/src/pro/envi: Makefile.in diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/interpol.pro gdl/src/pro/interpol.pro --- gdl-0.9.3/src/pro/interpol.pro 2012-12-27 09:22:44.000000000 -0700 @@ -19362,11 +41089,30 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/loadct.pro gd end +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/Makefile.am gdl/src/pro/Makefile.am +--- gdl-0.9.3/src/pro/Makefile.am 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/pro/Makefile.am 2013-03-21 14:04:04.649823919 -0600 +@@ -12,6 +12,7 @@ + dialog_message.pro \ + dialog_pickfile.pro \ + dist.pro \ ++ doc_library.pro \ + escape_special_char.pro \ + factorial.pro \ + file_basename.pro \ +@@ -47,6 +48,7 @@ + meanabsdev.pro \ + moment.pro \ + norm.pro \ ++ online_help.pro \ + path_sep.pro \ + ploterr.pro \ + poly.pro \ Only in gdl-0.9.3/src/pro: Makefile.in diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/matrix_multiply.pro gdl/src/pro/matrix_multiply.pro --- gdl-0.9.3/src/pro/matrix_multiply.pro 2012-12-27 09:22:44.000000000 -0700 -+++ gdl/src/pro/matrix_multiply.pro 2013-02-25 17:04:31.367153504 -0700 -@@ -5,26 +5,56 @@ ++++ gdl/src/pro/matrix_multiply.pro 2013-03-21 14:04:04.720823591 -0600 +@@ -5,26 +5,54 @@ ; ; AUTHOR: Philippe Prugniel 2008/02/29 ; @@ -19374,7 +41120,8 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/matrix_multip +; Modifications: +; 05-Feb-2013: when GDL is compiled with Eigen Lib., we use internal +; fast MATMUL function. It is not ready for Complex/DoubleComplex -+; ++; 01-Mar-2013: with Eigen Lib, matmul function is OK with complex values, removed ++; some code +; Copyright (C) 2008, 2013. ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by @@ -19384,17 +41131,6 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/matrix_multip ;----------------------------------------------------------------------------- -function matrix_multiply, a, b, ATRANSPOSE=atr, BTRANSPOSE=btr - on_error, 2 -- -- IF (N_PARAMS() NE 2) THEN BEGIN -- message, 'Incorrect number of arguments.' -- ENDIF --; -- case (1) of -- keyword_set(atr) and not keyword_set(btr): return, transpose(a) # b -- keyword_set(btr) and not keyword_set(atr): return, a # transpose(b) -- keyword_set(atr) and keyword_set(btr): return, transpose(a) # transpose(b) -- else : return, a # b -- endcase +function MATRIX_MULTIPLY, a, b, ATRANSPOSE=atr, BTRANSPOSE=btr, $ + help=help, debug=debug +; @@ -19420,10 +41156,17 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/matrix_multip +endif else begin + type=MATMUL(/available,/quiet) +endelse -+; -+if (SIZE(a,/type) EQ 6) OR (SIZE(a,/type) EQ 9) then type=0 -+if (SIZE(b,/type) EQ 6) OR (SIZE(b,/type) EQ 9) then type=0 -+; + +- IF (N_PARAMS() NE 2) THEN BEGIN +- message, 'Incorrect number of arguments.' +- ENDIF +-; +- case (1) of +- keyword_set(atr) and not keyword_set(btr): return, transpose(a) # b +- keyword_set(btr) and not keyword_set(atr): return, a # transpose(b) +- keyword_set(atr) and keyword_set(btr): return, transpose(a) # transpose(b) +- else : return, a # b +- endcase +if (type EQ 0) then begin + case (1) of + KEYWORD_SET(atr) and not KEYWORD_SET(btr): return, TRANSPOSE(a) # b @@ -19437,6 +41180,222 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/matrix_multip ; end +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/online_help.pro gdl/src/pro/online_help.pro +--- gdl-0.9.3/src/pro/online_help.pro 1969-12-31 17:00:00.000000000 -0700 ++++ gdl/src/pro/online_help.pro 2013-03-05 06:26:06.000000000 -0700 +@@ -0,0 +1,212 @@ ++;+ ++; ++; NAME: ONLINE_HELP ++; ++; PURPOSE: accessing the documentation, the general one or for a given ++; procedure of function (intrinsic or not) ++; ++; CATEGORY: documentation ++; ++; CALLING SEQUENCE: ( ? or ONLINE_HELP ) or ( ?fft or ONLINE_HELP, 'fft') ++; ++; INPUTS: no mandatory ones ++; ++; OPTIONAL INPUTS: name of a procedure, function or code ++; ++; KEYWORD PARAMETERS: ++; ++; OUTPUTS: none ++; ++; OPTIONAL OUTPUTS: none ++; ++; COMMON BLOCKS: none ++; ++; SIDE EFFECTS: may or not succeed to start a WEB browser. ++; ++; RESTRICTIONS: ++; ++; 1/ except if a copy of the "GDL.pdf" is locally available ++; and in the !path, an internet connection is mandatory ... ++; ++; 2/ the result is very sensitive to the version of the WEB browser ++; and which plugings (and pluging versions) are available. ++; ++; PROCEDURE: straitforward ++; ++; EXAMPLE: ONLINE_HELP, 'fft', browser='midori' ++; ++; MODIFICATION HISTORY: ++; -- 01-March-2013: creation by Alain Coulais, ++; ++; LICENCE: This code is under GNU GPL v2 or later. ++; ++; ++; Very preliminary concept. the goal is to link to internal pages of ++; the PDF file "gdl.pdf" (eventually downloaded if not found) ++; (currently at: http://gnudatalanguage.sourceforge.net/gdl.pdf) ++; and also starting online HTML doc. ++; ++; The PDF file is currently at: http://gnudatalanguage.sourceforge.net/gdl.pdf ++; Following Adobe Documention, direct links to page, chapter shall be possible ++; http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf ++; We use now only the search option ralated to Acroread viewer. ++; Up to now, no equivalent functions inside alternative PDF ++; readers (evince, xpdf) but is is supposed to be OK with "pdf.js" ++; pluging in Firefox https://github.com/mozilla/pdf.js/issues/1875 ++; ++; We have to consider to have local HTML version of the documentation. ++; ++;- ++pro ONLINE_HELP, name, nopdf=nopdf, nohtml=nohtml, nokey=nokey, $ ++ book=book, browser=browser, $ ++ path2pdf=path2pdf, path2key=path2key, link2html=link2htlm, $ ++ test=test, debug=debug, help=help, verbose=verbose ++; ++ON_ERROR, 2 ++; ++if ~KEYWORD_SET(test) then ON_ERROR, 2 ++; ++if KEYWORD_SET(help) then begin ++ print, 'pro ONLINE_HELP, name, nopdf=nopdf, nohtml=nohtml, nokey=nokey, $' ++ print, ' book=book, browser=browser, $' ++ print, ' path2pdf=path2pdf, path2key=path2key, link2html=link2htlm, $' ++ print, ' test=test, debug=debug, help=help, verbose=verbose' ++ print, '' ++ return ++endif ++; ++if N_PARAMS() EQ 0 then name='' ++; ++if N_PARAMS() EQ 1 then name=STRCOMPRESS(name,/remove_all) ++; ++; do we have access to X11 ?? ++; (we may consider using Lynx (tested succesfully) but is it really ++; useful ?) ++; ++status=EXECUTE('xy=GET_SCREEN_SIZE()') ++if (status EQ 0) then begin ++ MESSAGE, 'Since we are unable to connect to X Windows display, no ONLINE HELP' ++endif ++; ++if KEYWORD_SET(book) then begin ++ MESSAGE, /continue, 'This option is not available' ++endif ++; ++; setting a default browser if not provided ++; this code was tested with konqueror, midori and firefox ++; ++if ~KEYWORD_SET(browser) then begin ++ ;; classical default ! ++ browser='firefox' ++ ;; ++ ;; on some GNU/Linux systems, a BROWSER is defined ... ++ default_browser=GETENV('BROWSER') ++ if (STRLEN(default_browser) GT 0) then browser=default_browser ++ ;; ++ ;; on OSX, it seems to be better to use "open" but this is not ++ ;; working over ssh -X connection ... (suggestion welcome !) ++ ;; ++ if (!version.os EQ 'darwin') then browser='open' ++endif ++; ++; we check if the default or selected brower is in the path ++; ++SPAWN, 'which '+browser, ok, error ++; ++if (STRLEN(ok) EQ 0) then begin ++ MESSAGE, /continue, 'WEB Browser not found : '+browser ++ MESSAGE, 'Please provide the name (+path) to the browser you want to use' ++endif ++; ++space=' ' ++background=' &' ++; ++; link to IDL exelis in-line documentation ++; ++link1='' ++if ~KEYWORD_SET(nohtml) then begin ++ if ~KEYWORD_SET(link2html) then link2html='http://www.exelisvis.com/docs/' ++ suffixe='.html' ++ ;; ++ if STRLEN(name) GT 0 then begin ++ link1=space+link2html+STRUPCASE(name)+suffixe ++ endif else begin ++ link1=space+link2html ++ endelse ++endif ++; ++; link to PDF ++; if not found in the !PATH, this file is downloaded the first time ++; ++link2='' ++if ~KEYWORD_SET(nopdf) then begin ++ path2pdf='http://gnudatalanguage.sourceforge.net/' ++ local_pdf=FILE_WHICH(!path, 'gdl.pdf',/include_current_dir) ++ ;; ++ ;; if no "gdl.pdf" in the !Path, trying to download it ++ if STRLEN(local_pdf) EQ 0 then begin ++ script='' ++ SPAWN, 'which wget', res ++ if STRLEN(res) GT 0 then begin ++ script='wget ' ++ endif else begin ++ SPAWN, 'which curl', res ++ if STRLEN(res) GT 0 then script='curl -O ' ++ endelse ++ if (STRLEN(script) GT 0) then begin ++ SPAWN, script+path2pdf+'gdl.pdf', ok, pb ++ endif ++ local_pdf=FILE_WHICH(!path, 'gdl.pdf',/include_current_dir) ++ endif ++ ;; ++ if (STRLEN(local_pdf) GT 0) then begin ++ if STRLEN(name) GT 0 then begin ++ ;; activating the search capability inside PDF, ++ ;; worked on Acroread pluging ++ ;; should worked withing ++ link2='file://'+FILE_EXPAND_PATH(local_pdf)+'#search="'+name+'"' ++ endif else begin ++ link2='file://'+FILE_EXPAND_PATH(local_pdf) ++ endelse ++ endif else begin ++ MESSAGE, /continue, 'GDL pdf documentaion not found :(' ++ endelse ++endif ++; ++link3='' ++if ~KEYWORD_SET(nokey) then begin ++ path2key='http://aramis.obspm.fr/~coulais/IDL_et_GDL/' ++ ;; ++ if (STRLEN(name) GT 0) then begin ++ ;; is it a .PRO file ?? ++ pro_file=FILE_WHICH(name+'.pro') ++ if STRLEN(pro_file) GT 0 then begin ++ link3='file://'+pro_file+space ++ link3=link3+path2key+'Matrice_IDLvsGDL.html#'+STRUPCASE(STRMID(name,0,1)) ++ endif else begin ++ link3=path2key+'known_keywords.html#GDL_'+STRUPCASE(name) ++ endelse ++ endif else begin ++ link3=path2key+'Matrice_IDLvsGDL.html' ++ endelse ++endif ++; ++; line by line the command used by browser ++; ++if keyword_set(verbose) then begin ++ MESSAGE, /continue, 'link2html= : '+link2html ++ MESSAGE, /continue, 'path2pdf = : '+path2pdf ++ MESSAGE, /continue, 'path2key = : '+path2key ++endif ++; ++command=browser+space+link1+space+link2+space+link3+background ++; ++if KEYWORD_SET(debug) then begin ++ print, command ++ STOP ++endif ++SPAWN, command ++; ++if KEYWORD_SET(test) then stop ++; ++end diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/pro/wmenu.pro gdl/src/pro/wmenu.pro --- gdl-0.9.3/src/pro/wmenu.pro 2012-12-27 09:22:44.000000000 -0700 +++ gdl/src/pro/wmenu.pro 2013-01-13 16:49:28.000000000 -0700 @@ -19753,7 +41712,1383 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/prognodeexpr.cpp } ///////// +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/specializations.hpp gdl/src/specializations.hpp +--- gdl-0.9.3/src/specializations.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/specializations.hpp 2013-03-21 14:04:04.484824682 -0600 +@@ -644,27 +644,35 @@ + BaseGDL::IOMode oMode); + + ++// template<> ++// void Data_< SpDString>::Construct(); ++// template<> ++// void Data_< SpDComplex>::Construct(); ++// template<> ++// void Data_< SpDComplexDbl>::Construct(); ++template<> ++void Data_< SpDPtr>::Construct(); ++template<> ++void Data_< SpDObj>::Construct(); ++// template<> ++// void Data_< SpDString>::ConstructTo0(); ++// template<> ++// void Data_< SpDComplex>::ConstructTo0(); ++// template<> ++// void Data_< SpDComplexDbl>::ConstructTo0(); ++// template<> ++// void Data_< SpDString>::Destruct(); ++// template<> ++// void Data_< SpDComplex>::Destruct(); ++// template<> ++// void Data_< SpDComplexDbl>::Destruct(); + template<> +-void Data_< SpDString>::Construct(); ++void Data_< SpDPtr>::Destruct(); + template<> +-void Data_< SpDComplex>::Construct(); +-template<> +-void Data_< SpDComplexDbl>::Construct(); +-template<> +-void Data_< SpDString>::ConstructTo0(); +-template<> +-void Data_< SpDComplex>::ConstructTo0(); +-template<> +-void Data_< SpDComplexDbl>::ConstructTo0(); +-template<> +-void Data_< SpDString>::Destruct(); +-template<> +-void Data_< SpDComplex>::Destruct(); +-template<> +-void Data_< SpDComplexDbl>::Destruct(); ++void Data_< SpDObj>::Destruct(); + + // GetAsIndex/GetAsIndexStrict +-template<> ++ template<> + SizeT Data_::GetAsIndex( SizeT i) const; + template<> + SizeT Data_::GetAsIndexStrict( SizeT i) const; Only in gdl-0.9.3/src: .#tmp_scratch.cpp +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/typedefs.hpp gdl/src/typedefs.hpp +--- gdl-0.9.3/src/typedefs.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/typedefs.hpp 2013-03-21 14:04:04.497824622 -0600 +@@ -58,15 +58,21 @@ + #include + // #include + +-// undef for releases (should not give diagnostics) +-// define for the CVS (where the default sizes can easily be adjusted) +-//#define GDL_CVS_VERSION +-#undef GDL_CVS_VERSION ++#undef USE_MPFR + +-#ifdef GDL_CVS_VERSION +-#include ++#ifdef USE_MPFR ++#include "mpreal.h" + #endif + ++// // undef for releases (should not give diagnostics) ++// // define for the CVS (where the default sizes can easily be adjusted) ++// #define GDL_CVS_VERSION ++// //#undef GDL_CVS_VERSION ++// // ? ++// #ifdef GDL_CVS_VERSION ++// #include ++// #endif ++ + //#define TRACE_OMP_CALLS + #undef TRACE_OMP_CALLS + +@@ -79,6 +85,7 @@ + // SA: fixing bug no. 3296360 + typedef unsigned long long int SizeT; + typedef long long int RangeT; ++typedef long long int OMPInt; + + const SizeT MAXRANK=8; // arrays are limited to 8 dimensions + const std::string MAXRANK_STR("8"); // for use in strings (error messages) +@@ -110,6 +117,7 @@ + #ifdef _MSC_VER + typedef __int64 DLong64; + typedef unsigned __int64 DULong64; ++ + #else + //typedef long int DLong64; + //typedef unsigned long int DULong64; +@@ -117,6 +125,19 @@ + typedef unsigned long long int DULong64; + #endif + ++#ifdef USE_MPFR ++ ++typedef __int128 DLong128; ++typedef unsigned __int128 DULong128; ++ ++typedef long double DLDouble; ++typedef std::complex DComplexLDbl; ++ ++ ++typedef mpfr::mpreal DArbitrary; ++#endif ++ ++ + typedef short DInt; + typedef unsigned short DUInt; + typedef int DLong; +@@ -126,9 +147,8 @@ + typedef std::string DString; + typedef SizeT DPtr; // ptr to heap + typedef DPtr DObj; // ptr to object heap +-typedef std::complex DComplex; +-typedef std::complex DComplexDbl; +- ++typedef std::complex DComplex; ++typedef std::complex DComplexDbl; + + // list of identifiers (used in several places) + typedef std::deque IDList; +@@ -352,388 +372,6 @@ + T* Release() { T* r=container; container=NULL; return r;} + }; + +-// #define GDLARRAY_CACHE +-#undef GDLARRAY_CACHE +- +-#define GDLARRAY_DEBUG +-// #undef GDLARRAY_DEBUG +- +-// const SizeT smallArraySize = 27; +-// const SizeT maxArrayCache = 1000 * 1000; // ComplexDbl is 16 bytes +- +-template +-class GDLArray +-{ +-private: +- enum GDLArrayConstants +- { +- smallArraySize = 27, +- maxCache = 1000 * 1000 // ComplexDbl is 16 bytes +- }; +- +- typedef T Ty; +- +-#ifdef GDLARRAY_CACHE +- +- static SizeT cacheSize; +- static T* cache; +- static T* Cached( SizeT newSize); +-#endif +- +- T scalar[ smallArraySize]; +- T* buf; +- SizeT sz; +- +-public: +- GDLArray() throw() : buf( NULL), sz( 0) {} +- +-#ifndef GDLARRAY_CACHE +- +- GDLArray( const GDLArray& cp) : sz( cp.size()) +- { +- try { +- buf = (cp.size() > smallArraySize) ? new T[ cp.size()] : scalar; +- } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } +-/*#pragma omp parallel if (sz >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- std::memcpy(buf,cp.buf,sz*sizeof(T)); +- +-// for( SizeT i=0; i smallArraySize) ? new T[ s] : scalar; +- } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } +- } +- +- GDLArray( T val, SizeT s) : sz( s) +- { +- try { +- buf = (s > smallArraySize) ? new T[ s] : scalar; +- } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } +-/*#pragma omp parallel if (sz >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- for( SizeT i=0; i smallArraySize ) ? new T[ s]: scalar; +- } +- catch ( std::bad_alloc& ) { ThrowGDLException ( "Array requires more memory than available" ); } +-/*#pragma omp parallel if (sz >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- +- std::memcpy(buf,arr,sz*sizeof(T)); +-// for( SizeT i=0; i= sz) +- assert( ix < sz); +- return buf[ ix]; +- } +- const T& operator[]( SizeT ix) const throw() +- { +-// if( ix >= sz) // debug +- assert( ix < sz); +- return buf[ ix]; +- } +- +-// private: // disable +-// only used (indirect) by DStructGDL::DStructGDL(const DStructGDL& d_) +-void InitFrom( const GDLArray& right ) +-{ +-// // assert( sz == right.size()); +-// if ( sz != right.size() ) +-// ThrowGDLException ( "GDLArray::operator= operands have not same size (this: " + i2s ( sz ) +", right: " + i2s ( right.size() ) + ")"); +- assert( &right != this); +- assert ( sz == right.size() ); +- std::memcpy(buf,right.buf,sz*sizeof(T)); +-} +- +-GDLArray& operator= ( const GDLArray& right ) +-{ +-// if ( sz != right.size() ) +-// ThrowGDLException ( "GDLArray::operator= operands have not same size (this: " + i2s ( sz ) +", right: " + i2s ( right.size() ) + ")"); +- +- assert( this != &right); +- assert( sz == right.size()); +-// if ( &right != this ) +- { +-// if ( sz == right.size() ) +- { +- /*#pragma omp parallel if (sz >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +- { +- #pragma omp for*/ +- for ( SizeT i=0; ismallArraySize ) ? new T[ sz] : scalar; +- /*#pragma omp parallel if (sz >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +- { +- #pragma omp for*/ +- for ( SizeT i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- for( SizeT i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- for( SizeT i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- for( SizeT i=0; i= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- for( SizeT i=0; i smallArraySize ) +- { +- try +- { +- buf = new T[ newSz]; +- } +- catch ( std::bad_alloc& ) +- { +- ThrowGDLException ( "Array requires more memory than available" ); +- } +- } +- else +- { +-// default constructed instances have buf == NULL and size == 0 +-// make sure buf is set corectly if such instances are resized +- buf = scalar; +- } +- sz = newSz; +-// assert ( newSz > sz ); +-// if ( newSz > smallArraySize ) +-// { +-// try +-// { +-// T* newBuf = new T[ newSz]; +-// /*#pragma omp parallel if (sz >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-// { +-// #pragma omp for*/ +-// for ( SizeT i=0; i buf[ i]) res = buf[ i]; +-// return res; +-// } +-// T max() const +-// { +-// T res = buf[ 0]; +-// for( SizeT i=1; i +-inline void GDLArray::InitFrom( const GDLArray& right ) +-{ +- assert( &right != this); +- assert ( sz == right.size() ); +- for ( SizeT i=0; i +-inline GDLArray::GDLArray( const GDLArray& cp) : sz( cp.size()) +- { +- try { +- buf = (cp.size() > smallArraySize) ? new Ty[ cp.size()] : scalar; +- } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } +-/*#pragma omp parallel if (sz >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- for( SizeT i=0; i +-inline GDLArray::GDLArray( const Ty* arr, SizeT s) : sz( s) +- { +- try { +- buf = (s > smallArraySize) ? new Ty[ s]: scalar; +- } catch (std::bad_alloc&) { ThrowGDLException("Array requires more memory than available"); } +-/*#pragma omp parallel if (sz >= CpuTPOOL_MIN_ELTS && (CpuTPOOL_MAX_ELTS == 0 || CpuTPOOL_MAX_ELTS <= sz)) +-{ +-#pragma omp for*/ +- for( SizeT i=0; i +-// GDLArray pow(const GDLArray& left, +-// const GDLArray& right) +-// { +-// GDLArray res( left.size); +- +-// for( SizeT i=0; i +-// GDLArray pow(const GDLArray left, const Ty& right); +-// template +-// GDLArray pow(const Ty& left, const GDLArray& right); + + // this data structure is optimized for list sizes < ExprListDefaultLength + // ExprListDefaultLength should be set such that it will probably never exceed +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/typetraits.cpp gdl/src/typetraits.cpp +--- gdl-0.9.3/src/typetraits.cpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/typetraits.cpp 2013-03-21 14:04:04.501824603 -0600 +@@ -26,10 +26,6 @@ + const DType SpDByte::t=GDL_BYTE; // type ID + const string SpDByte::str("BYTE"); // type string + const DByte SpDByte::zero=0; +-const bool SpDByte::IS_INTEGER=true; +-const bool SpDByte::IS_SIGNED=false; +-const bool SpDByte::IS_NUMERIC=true; +-const bool SpDByte::IS_COMPLEX=false; + BaseGDL* SpDByte::GetTag() const { return new SpDByte(*this);} + DType SpDByte::Type() const { return t;} + const std::string& SpDByte::TypeStr() const { return str;} +@@ -37,10 +33,6 @@ + const DType SpDInt::t=GDL_INT; // type ID + const string SpDInt::str("INT"); // type string + const DInt SpDInt::zero=0; +-const bool SpDInt::IS_INTEGER=true; +-const bool SpDInt::IS_SIGNED=true; +-const bool SpDInt::IS_NUMERIC=true; +-const bool SpDInt::IS_COMPLEX=false; + BaseGDL* SpDInt::GetTag() const { return new SpDInt(*this);} + DType SpDInt::Type() const { return t;} + const std::string& SpDInt::TypeStr() const { return str;} +@@ -48,10 +40,6 @@ + const DType SpDUInt::t=GDL_UINT; // type ID + const string SpDUInt::str("UINT"); // type string + const DUInt SpDUInt::zero=0; +-const bool SpDUInt::IS_INTEGER=true; +-const bool SpDUInt::IS_SIGNED=false; +-const bool SpDUInt::IS_NUMERIC=true; +-const bool SpDUInt::IS_COMPLEX=false; + BaseGDL* SpDUInt::GetTag() const { return new SpDUInt(*this);} + DType SpDUInt::Type() const { return t;} + const std::string& SpDUInt::TypeStr() const { return str;} +@@ -60,10 +48,6 @@ + const DType SpDLong::t=GDL_LONG; // type ID + const string SpDLong::str("LONG"); // type string + const DLong SpDLong::zero=0; +-const bool SpDLong::IS_INTEGER=true; +-const bool SpDLong::IS_SIGNED=true; +-const bool SpDLong::IS_NUMERIC=true; +-const bool SpDLong::IS_COMPLEX=false; + BaseGDL* SpDLong::GetTag() const { return new SpDLong(*this);} + DType SpDLong::Type() const { return t;} + const std::string& SpDLong::TypeStr() const { return str;} +@@ -71,10 +55,6 @@ + const DType SpDULong::t=GDL_ULONG; // type ID + const string SpDULong::str("ULONG"); // type string + const DULong SpDULong::zero=0; +-const bool SpDULong::IS_INTEGER=true; +-const bool SpDULong::IS_SIGNED=false; +-const bool SpDULong::IS_NUMERIC=true; +-const bool SpDULong::IS_COMPLEX=false; + BaseGDL* SpDULong::GetTag() const { return new SpDULong(*this);} + DType SpDULong::Type() const { return t;} + const std::string& SpDULong::TypeStr() const { return str;} +@@ -82,10 +62,6 @@ + const DType SpDLong64::t=GDL_LONG64; // type ID + const string SpDLong64::str("LONG64"); // type string + const DLong64 SpDLong64::zero=0; +-const bool SpDLong64::IS_INTEGER=true; +-const bool SpDLong64::IS_SIGNED=true; +-const bool SpDLong64::IS_NUMERIC=true; +-const bool SpDLong64::IS_COMPLEX=false; + BaseGDL* SpDLong64::GetTag() const { return new SpDLong64(*this);} + DType SpDLong64::Type() const { return t;} + const std::string& SpDLong64::TypeStr() const { return str;} +@@ -93,10 +69,6 @@ + const DType SpDULong64::t=GDL_ULONG64; // type ID + const string SpDULong64::str("ULONG64"); // type string + const DULong64 SpDULong64::zero=0; +-const bool SpDULong64::IS_INTEGER=true; +-const bool SpDULong64::IS_SIGNED=false; +-const bool SpDULong64::IS_NUMERIC=true; +-const bool SpDULong64::IS_COMPLEX=false; + BaseGDL* SpDULong64::GetTag() const { return new SpDULong64(*this);} + DType SpDULong64::Type() const { return t;} + const std::string& SpDULong64::TypeStr() const { return str;} +@@ -104,10 +76,6 @@ + const DType SpDFloat::t=GDL_FLOAT; // type ID + const string SpDFloat::str("FLOAT"); // type string + const DFloat SpDFloat::zero=0.0; +-const bool SpDFloat::IS_INTEGER=false; +-const bool SpDFloat::IS_SIGNED=true; +-const bool SpDFloat::IS_NUMERIC=true; +-const bool SpDFloat::IS_COMPLEX=false; + BaseGDL* SpDFloat::GetTag() const { return new SpDFloat(*this);} + DType SpDFloat::Type() const { return t;} + const std::string& SpDFloat::TypeStr() const { return str;} +@@ -115,10 +83,6 @@ + const DType SpDDouble::t=GDL_DOUBLE; // type ID + const string SpDDouble::str("DOUBLE"); // type string + const DDouble SpDDouble::zero=0.0; +-const bool SpDDouble::IS_INTEGER=false; +-const bool SpDDouble::IS_SIGNED=true; +-const bool SpDDouble::IS_NUMERIC=true; +-const bool SpDDouble::IS_COMPLEX=false; + BaseGDL* SpDDouble::GetTag() const { return new SpDDouble(*this);} + DType SpDDouble::Type() const { return t;} + const std::string& SpDDouble::TypeStr() const { return str;} +@@ -126,10 +90,6 @@ + const DType SpDString::t=GDL_STRING; // type ID + const string SpDString::str("STRING"); // type string + const DString SpDString::zero(""); // zero string +-const bool SpDString::IS_INTEGER=false; +-const bool SpDString::IS_SIGNED=false; +-const bool SpDString::IS_NUMERIC=false; +-const bool SpDString::IS_COMPLEX=false; + BaseGDL* SpDString::GetTag() const { return new SpDString(*this);} + DType SpDString::Type() const { return t;} + const std::string& SpDString::TypeStr() const { return str;} +@@ -137,10 +97,6 @@ + const DType SpDStruct::t=GDL_STRUCT; // type ID + const string SpDStruct::str("STRUCT"); // type string + const SpDStruct::Ty SpDStruct::zero=0; // zero struct, special meaning +-const bool SpDStruct::IS_INTEGER=false; +-const bool SpDStruct::IS_SIGNED=false; +-const bool SpDStruct::IS_NUMERIC=false; +-const bool SpDStruct::IS_COMPLEX=false; + BaseGDL* SpDStruct::GetTag() const + { + SpDStruct* newTag = new SpDStruct(*this); +@@ -153,10 +109,6 @@ + const DType SpDPtr::t=GDL_PTR; // type ID + const string SpDPtr::str("POINTER"); // type string + const DPtr SpDPtr::zero=0; // zero ptr +-const bool SpDPtr::IS_INTEGER=false; +-const bool SpDPtr::IS_SIGNED=false; +-const bool SpDPtr::IS_NUMERIC=false; +-const bool SpDPtr::IS_COMPLEX=false; + BaseGDL* SpDPtr::GetTag() const { return new SpDPtr(*this);} + DType SpDPtr::Type() const { return t;} + const std::string& SpDPtr::TypeStr() const { return str;} +@@ -164,10 +116,6 @@ + const DType SpDObj::t=GDL_OBJ; // type ID + const string SpDObj::str("OBJREF"); // type string + const DObj SpDObj::zero=0; // zero ptr/obj +-const bool SpDObj::IS_INTEGER=false; +-const bool SpDObj::IS_SIGNED=false; +-const bool SpDObj::IS_NUMERIC=false; +-const bool SpDObj::IS_COMPLEX=false; + BaseGDL* SpDObj::GetTag() const { return new SpDObj(*this);} + DType SpDObj::Type() const { return t;} + const std::string& SpDObj::TypeStr() const { return str;} +@@ -175,10 +123,6 @@ + const DType SpDComplex::t=GDL_COMPLEX; // type ID + const string SpDComplex::str("COMPLEX"); // type string + const DComplex SpDComplex::zero(0.0,0.0); +-const bool SpDComplex::IS_INTEGER=false; +-const bool SpDComplex::IS_SIGNED=true; +-const bool SpDComplex::IS_NUMERIC=true; +-const bool SpDComplex::IS_COMPLEX=true; + BaseGDL* SpDComplex::GetTag() const { return new SpDComplex(*this);} + DType SpDComplex::Type() const { return t;} + const std::string& SpDComplex::TypeStr() const { return str;} +@@ -186,10 +130,6 @@ + const DType SpDComplexDbl::t=GDL_COMPLEXDBL; // type ID + const string SpDComplexDbl::str("DCOMPLEX"); // type string + const DComplexDbl SpDComplexDbl::zero(0.0,0.0); +-const bool SpDComplexDbl::IS_INTEGER=false; +-const bool SpDComplexDbl::IS_SIGNED=true; +-const bool SpDComplexDbl::IS_NUMERIC=true; +-const bool SpDComplexDbl::IS_COMPLEX=true; + BaseGDL* SpDComplexDbl::GetTag() const { return new SpDComplexDbl(*this);} + DType SpDComplexDbl::Type() const { return t;} + const std::string& SpDComplexDbl::TypeStr() const { return str;} +@@ -317,3 +257,89 @@ + SpDComplexDbl::SpDComplexDbl( const dimension& dim_): BaseGDL(dim_) {} + SpDComplexDbl::~SpDComplexDbl() {} + ++ ++ ++ ++/* ++ ++const bool SpDByte::IS_INTEGER=true; ++const bool SpDByte::IS_SIGNED=false; ++const bool SpDByte::IS_NUMERIC=true; ++const bool SpDByte::IS_COMPLEX=false; ++const bool SpDByte::IS_POD=true; ++const bool SpDByte::IS_CONVERTABLE=true; ++ ++const bool SpDInt::IS_INTEGER=true; ++const bool SpDInt::IS_SIGNED=true; ++const bool SpDInt::IS_NUMERIC=true; ++const bool SpDInt::IS_COMPLEX=false; ++const bool SpDInt::IS_POD=true; ++const bool SpDInt::IS_CONVERTABLE=true; ++ ++const bool SpDUInt::IS_INTEGER=true; ++const bool SpDUInt::IS_SIGNED=false; ++const bool SpDUInt::IS_NUMERIC=true; ++const bool SpDUInt::IS_COMPLEX=false; ++ ++const bool SpDLong::IS_INTEGER=true; ++const bool SpDLong::IS_SIGNED=true; ++const bool SpDLong::IS_NUMERIC=true; ++const bool SpDLong::IS_COMPLEX=false; ++ ++const bool SpDULong::IS_INTEGER=true; ++const bool SpDULong::IS_SIGNED=false; ++const bool SpDULong::IS_NUMERIC=true; ++const bool SpDULong::IS_COMPLEX=false; ++ ++const bool SpDLong64::IS_INTEGER=true; ++const bool SpDLong64::IS_SIGNED=true; ++const bool SpDLong64::IS_NUMERIC=true; ++const bool SpDLong64::IS_COMPLEX=false; ++ ++const bool SpDFloat::IS_INTEGER=false; ++const bool SpDFloat::IS_SIGNED=true; ++const bool SpDFloat::IS_NUMERIC=true; ++const bool SpDFloat::IS_COMPLEX=false; ++ ++const bool SpDULong64::IS_INTEGER=true; ++const bool SpDULong64::IS_SIGNED=false; ++const bool SpDULong64::IS_NUMERIC=true; ++const bool SpDULong64::IS_COMPLEX=false; ++ ++const bool SpDDouble::IS_INTEGER=false; ++const bool SpDDouble::IS_SIGNED=true; ++const bool SpDDouble::IS_NUMERIC=true; ++const bool SpDDouble::IS_COMPLEX=false; ++ ++const bool SpDString::IS_INTEGER=false; ++const bool SpDString::IS_SIGNED=false; ++const bool SpDString::IS_NUMERIC=false; ++const bool SpDString::IS_COMPLEX=false; ++ ++const bool SpDStruct::IS_INTEGER=false; ++const bool SpDStruct::IS_SIGNED=false; ++const bool SpDStruct::IS_NUMERIC=false; ++const bool SpDStruct::IS_COMPLEX=false; ++ ++const bool SpDPtr::IS_INTEGER=false; ++const bool SpDPtr::IS_SIGNED=false; ++const bool SpDPtr::IS_NUMERIC=false; ++const bool SpDPtr::IS_COMPLEX=false; ++ ++const bool SpDObj::IS_INTEGER=false; ++const bool SpDObj::IS_SIGNED=false; ++const bool SpDObj::IS_NUMERIC=false; ++const bool SpDObj::IS_COMPLEX=false; ++ ++const bool SpDComplex::IS_INTEGER=false; ++const bool SpDComplex::IS_SIGNED=true; ++const bool SpDComplex::IS_NUMERIC=true; ++const bool SpDComplex::IS_COMPLEX=true; ++ ++const bool SpDComplexDbl::IS_INTEGER=false; ++const bool SpDComplexDbl::IS_SIGNED=true; ++const bool SpDComplexDbl::IS_NUMERIC=true; ++const bool SpDComplexDbl::IS_COMPLEX=true; ++ ++ ++*/ +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/src/typetraits.hpp gdl/src/typetraits.hpp +--- gdl-0.9.3/src/typetraits.hpp 2012-12-27 09:22:44.000000000 -0700 ++++ gdl/src/typetraits.hpp 2013-03-21 14:04:04.512824553 -0600 +@@ -25,6 +25,7 @@ + + #include "basegdl.hpp" + #include "dstructdesc.hpp" ++#include "gdlarray.hpp" + + // define type parameterization here + struct SpDByte: public BaseGDL +@@ -36,9 +37,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DByte Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -48,10 +46,22 @@ + static const std::string str; + static const DByte zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = true; ++ static const bool IS_SIGNED = false; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DByte Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -68,9 +78,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DInt Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -80,10 +87,22 @@ + static const std::string str; + static const DInt zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = true; ++ static const bool IS_SIGNED = true; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DInt Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -100,9 +119,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DUInt Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -112,10 +128,22 @@ + static const std::string str; + static const DUInt zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = true; ++ static const bool IS_SIGNED = false; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DUInt Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -132,9 +160,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DLong Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -144,10 +169,22 @@ + static const std::string str; + static const DLong zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = true; ++ static const bool IS_SIGNED = true; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DLong Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -164,9 +201,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DULong Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -176,10 +210,22 @@ + static const std::string str; + static const DULong zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = true; ++ static const bool IS_SIGNED = false; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DULong Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -196,9 +242,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DLong64 Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -208,10 +251,22 @@ + static const std::string str; + static const DLong64 zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = true; ++ static const bool IS_SIGNED = true; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DLong64 Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -228,9 +283,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DULong64 Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -240,10 +292,22 @@ + static const std::string str; + static const DULong64 zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = true; ++ static const bool IS_SIGNED = false; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DULong64 Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -260,9 +324,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DFloat Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -272,10 +333,22 @@ + static const std::string str; + static const DFloat zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = false; ++ static const bool IS_SIGNED = true; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = true; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DFloat Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -292,9 +365,6 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DDouble Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); +@@ -304,10 +374,23 @@ + static const std::string str; + static const DDouble zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ ++ static const bool IS_INTEGER = false; ++ static const bool IS_SIGNED = true; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = true; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = true; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DDouble Ty; ++ typedef GDLArray DataT; + + DType Type() const; + const std::string& TypeStr() const; +@@ -324,23 +407,32 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DString Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); + } + ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = false; ++ static const bool IS_SIGNED = false; ++ static const bool IS_NUMERIC = false; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = false; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DString Ty; ++ typedef GDLArray DataT; ++ + static const DType t; + static const std::string str; + static const Ty zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; +- + DType Type() const; + const std::string& TypeStr() const; + +@@ -378,23 +470,33 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef char Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return ( this->N_Elements() * desc->NBytes()); + } + ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ ++ static const bool IS_INTEGER = false; ++ static const bool IS_SIGNED = false; ++ static const bool IS_NUMERIC = false; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = false; ++ static const bool IS_CONVERTABLE = false; ++ ++ typedef char Ty; ++ typedef GDLArray DataT; // we are using char here ++ + static const DType t; + static const std::string str; + static const Ty zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; +- + DType Type() const; + const std::string& TypeStr() const; + +@@ -411,23 +513,32 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DPtr Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); + } + ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = false; ++ static const bool IS_SIGNED = false; ++ static const bool IS_NUMERIC = false; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = false; // due to ref counting ++ static const bool IS_CONVERTABLE = false; ++ ++ typedef DPtr Ty; ++ typedef GDLArray DataT; // on this level, DPtr is POD ++ + static const DType t; + static const std::string str; + static const Ty zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; +- + DType Type() const; + const std::string& TypeStr() const; + +@@ -444,23 +555,32 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DObj Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); + } + ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ static const bool IS_INTEGER = false; ++ static const bool IS_SIGNED = false; ++ static const bool IS_NUMERIC = false; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = false; ++ static const bool IS_POD = false; // due to ref counting ++ static const bool IS_CONVERTABLE = false; ++ ++ typedef DObj Ty; ++ typedef GDLArray DataT; // on this level, DObj is POD ++ + static const DType t; + static const std::string str; + static const Ty zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; +- + DType Type() const; + const std::string& TypeStr() const; + +@@ -476,23 +596,33 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DComplex Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); + } + ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ ++ static const bool IS_INTEGER = false; ++ static const bool IS_SIGNED = true; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = true; ++ static const bool IS_POD = false; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DComplex Ty; ++ typedef GDLArray DataT; // ATTENTION: srictly complex is non-pod ++ + static const DType t; + static const std::string str; + static const DComplex zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; +- + DType Type() const; + const std::string& TypeStr() const; + +@@ -508,23 +638,33 @@ + BaseGDL* GetInstance() const; + BaseGDL* GetEmptyInstance() const; + +- typedef DComplexDbl Ty; +- typedef GDLArray DataT; +- + SizeT NBytes() const + { + return (this->N_Elements() * sizeof( Ty)); + } + ++// static const bool IS_INTEGER; ++// static const bool IS_SIGNED; ++// static const bool IS_NUMERIC; ++// static const bool IS_COMPLEX; ++// static const bool IS_POD; ++// static const bool IS_CONVERTABLE; ++ ++ static const bool IS_SIGNED = true; ++ static const bool IS_NUMERIC = true; ++ static const bool IS_INTEGER = false; ++ static const bool IS_FLOAT = false; ++ static const bool IS_COMPLEX = true; ++ static const bool IS_POD = false; ++ static const bool IS_CONVERTABLE = true; ++ ++ typedef DComplexDbl Ty; ++ typedef GDLArray DataT; // ATTENTION: srictly complex is non-pod ++ + static const DType t; + static const std::string str; + static const DComplexDbl zero; + +- static const bool IS_INTEGER; +- static const bool IS_SIGNED; +- static const bool IS_NUMERIC; +- static const bool IS_COMPLEX; +- + DType Type() const; + const std::string& TypeStr() const; + diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/templates/cpp gdl/templates/cpp --- gdl-0.9.3/templates/cpp 1969-12-31 17:00:00.000000000 -0700 +++ gdl/templates/cpp 2004-12-09 08:10:21.000000000 -0700 @@ -19794,6 +43129,131 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/templates/h gdl/templ + * (at your option) any later version. * + * * + ***************************************************************************/ +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/testsuite/benchmark/bench_matrix_multiply.pro gdl/testsuite/benchmark/bench_matrix_multiply.pro +--- gdl-0.9.3/testsuite/benchmark/bench_matrix_multiply.pro 1969-12-31 17:00:00.000000000 -0700 ++++ gdl/testsuite/benchmark/bench_matrix_multiply.pro 2013-03-08 06:34:12.000000000 -0700 +@@ -0,0 +1,121 @@ ++; ++; AC 25 February 2013 ++; ++; First computation is using "#" operator. ++; the 4 computations after are using MATRIX_MULTIPLY() function, ++; eventualy calling Eigen3 code (a message will be issued if not) ++; ++pro BENCH_MATRIX_MULTIPLY, n1, n2, n3, $ ++ small=small, medium=medium, double=double, $ ++ complex=complex, dblecomplex=dblecomplex, $ ++ output_type=output_type, help=help, test=test ++; ++if KEYWORD_SET(help) then begin ++ print, 'pro BENCH_MATRIX_MULTPLY, n1, n2, n3, ' ++ print, ' small=small, medium=medium, double=double, $' ++ print, ' complex=complex, dblecomplex=dblecomplex, $' ++ print, ' output_type=output_type, help=help, test=test' ++ return ++endif ++; ++DEFSYSV, '!gdl', exist=it_is_GDL ++; ++if (it_is_GDL) then begin ++ having_eigen3=EXECUTE("type=MATMUL(/available, quiet=quiet)") ++ if (having_eigen3 EQ 0) then begin ++ print, 'You are trying testing new capabilities (Eigen3 usage)' ++ print, 'on a too OLD GDL version ! Please make tests on CVS version !' ++ return ++ endif ++endif ++; ++if N_PARAMS() EQ 0 then begin ++ colA=1000 ++ rowA=3000 ++ rowB=751 ++endif ++; ++if N_PARAMS() EQ 1 then begin ++ colA=n1 ++ rowA=n1 ++ rowB=n1 ++endif ++; ++if N_PARAMS() EQ 2 then begin ++ colA=n1 ++ rowA=n2 ++ rowB=n2 ++endif ++if N_PARAMS() EQ 3 then begin ++ colA=n1 ++ rowA=n2 ++ rowB=n3 ++endif ++; ++if KEYWORD_SET(medium) then begin ++ colA=colA/2 ++ rowA=rowA/2 ++ rowB=rowB/2 ++endif ++; ++if KEYWORD_SET(small) then begin ++ colA=colA/4 ++ rowA=rowA/4 ++ rowB=rowB/4 ++endif ++; ++colB=rowA ++; ++known_type=0 ++if KEYWORD_SET(dblecomplex) then begin ++ a=DCOMPLEXARR(colA ,rowA) ++ b=DCOMPLEXARR(colB ,rowB) ++ known_type=1 ++endif ++if KEYWORD_SET(complex) then begin ++ a=COMPLEXARR(colA ,rowA) ++ b=COMPLEXARR(colB ,rowB) ++ known_type=1 ++endif ++if KEYWORD_SET(double) then begin ++ a=RANDOMU(seed, colA, rowA, /DOUBLE) ++ b=RANDOMU(seed, colB, rowB, /DOUBLE) ++ known_type=1 ++endif ++if (known_type EQ 0) then begin ++ a=RANDOMU(seed, colA, rowA) ++ b=RANDOMU(seed, colB, rowB) ++endif ++; ++b_t=TRANSPOSE(b) ++a_t=TRANSPOSE(a) ++; ++HELP, a, b ++; ++txt='Matrix size are : [' +STRING(colA)+','+STRING(rowA) ++txt=txt+'] # ['+STRING(colB)+','+STRING(rowB)+']' ++print, STRCOMPRESS(txt) ++; ++txt_ref='Classic operator #, ' ++txt= 'Matrix_Multiply() , ' ++; ++t0=SYSTIME(1) & z=a # b & print, txt_ref+'a#b :', SYSTIME(1)-t0 ++t0=SYSTIME(1) & z=MATRIX_MULTIPLY(a,b) & print, txt+'a#b :', SYSTIME(1)-t0 ++t0=SYSTIME(1) & z=MATRIX_MULTIPLY(a_t,b,/at) & print, txt+'aT#b :', SYSTIME(1)-t0 ++t0=SYSTIME(1) & z=MATRIX_MULTIPLY(a,b_t,/bt) & print, txt+'a#bT :', SYSTIME(1)-t0 ++t0=SYSTIME(1) & z=MATRIX_MULTIPLY(a_t,b_t,/at,/bt) & print, txt+'aT#bT:', SYSTIME(1)-t0 ++; ++if KEYWORD_SET(test) then STOP ++; ++end ++; ++; ------------------------------ ++; ++pro BENCH_MATRIX_MULTIPLY_ALL, small=small ++; ++BENCH_MATRIX_MULTIPLY ++BENCH_MATRIX_MULTIPLY, /double ++BENCH_MATRIX_MULTIPLY, /complex ++BENCH_MATRIX_MULTIPLY, /dblecomplex ++; ++end Only in gdl-0.9.3/testsuite: launchtest.c diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/testsuite/Makefile.am gdl/testsuite/Makefile.am --- gdl-0.9.3/testsuite/Makefile.am 2012-12-27 09:22:44.000000000 -0700 @@ -19807,6 +43267,48 @@ diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/testsuite/Makefile.am test_systime.pro \ test_trisol.pro \ Only in gdl-0.9.3/testsuite: Makefile.in +diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/testsuite/test_bytscl.pro gdl/testsuite/test_bytscl.pro +--- gdl-0.9.3/testsuite/test_bytscl.pro 1969-12-31 17:00:00.000000000 -0700 ++++ gdl/testsuite/test_bytscl.pro 2013-03-21 11:30:42.000000000 -0600 +@@ -0,0 +1,38 @@ ++; ++; Alain C., 21 March 2013 ++; ++; draft: very preliminary version for testing BYTSCL(), ++; the last case is buggy. ++; ++pro TEST_BYTSCL ++; ++ramp=FINDGEN(10) ++; ++expected=BYTARR(10) ++expected[*]=[0,28,56,85,113,142,170,199,227,255] ++; ++resu=BYTSCL(ramp) ++; ++print, ARRAY_EQUAL(expected, resu) ++; ++expected_nan=BYTARR(10) ++expected_nan[6]=255 ++; ++expected_nan_flag=expected ++expected_nan_flag[5:6]=0 ++; ++; ++ramp_nan=ramp ++ramp_nan[5]=!values.f_nan ++ramp_nan[6]=!values.f_infinity ++; ++resu_nan=BYTSCL(ramp_nan) ++resu_nan_flag=BYTSCL(ramp_nan,/nan) ++; ++print, ARRAY_EQUAL(expected_nan, resu_nan) ++print, ARRAY_EQUAL(expected_nan_flag, resu_nan_flag) ++; ++print, 'not finished' ++ ++stop ++end diff -ru --unidirectional-new-file --exclude CVS gdl-0.9.3/testsuite/test_histo.pro gdl/testsuite/test_histo.pro --- gdl-0.9.3/testsuite/test_histo.pro 2012-12-27 09:22:44.000000000 -0700 +++ gdl/testsuite/test_histo.pro 2013-02-25 17:04:31.928151218 -0700 diff --git a/gdl-python.patch b/gdl-python.patch new file mode 100644 index 0000000..6553021 --- /dev/null +++ b/gdl-python.patch @@ -0,0 +1,15 @@ +diff -up gdl-0.9.3/CMakeLists.txt.python gdl-0.9.3/CMakeLists.txt +--- gdl-0.9.3/CMakeLists.txt.python 2013-03-21 14:21:33.649335754 -0600 ++++ gdl-0.9.3/CMakeLists.txt 2013-03-21 14:33:55.738083209 -0600 +@@ -562,6 +562,11 @@ if(PYTHON OR PYTHON_MODULE) + message("-- Found Python executable: ${PYTHON_EXECUTABLE}") + endif() + else() ++ if(PYTHONVERSION) ++ set(PythonLibs_FIND_VERSION ${PYTHONVERSION}) ++ else() ++ set(PythonLibs_FIND_VERSION 2) ++ endif() + find_package(PythonLibs) + include(FindPythonInterp) + endif() diff --git a/gdl.spec b/gdl.spec index 3c6fa24..2bf5be8 100644 --- a/gdl.spec +++ b/gdl.spec @@ -2,7 +2,7 @@ Name: gdl Version: 0.9.3 -Release: 5%{?dist} +Release: 6.cvs20130321%{?dist} Summary: GNU Data Language Group: Applications/Engineering @@ -29,6 +29,8 @@ Patch5: gdl-tests.patch Patch6: gdl-netcdf.patch # Build with system antlr library. Request for upstream change here: # https://sourceforge.net/tracker/index.php?func=detail&aid=2685215&group_id=97659&atid=618686 +# Patch to find the correct python version for cmake +Patch7: gdl-python.patch Patch13: gdl-0.9-antlr-cmake.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -114,6 +116,7 @@ popd %patch4 -p1 -b .test_ce %patch5 -p1 -b .tests %patch6 -p1 -b .netcdf +%patch7 -p1 -b .python rm ltmain.sh rm -r CMakeFiles @@ -140,7 +143,7 @@ make %{?_smp_mflags} popd #Build the python module pushd build-python -%{cmake} %{cmake_opts} -DPYTHON_MODULE=ON .. +%{cmake} %{cmake_opts} -DPYTHON_MODULE=ON -DPYTHON_VERSION=2.7 .. make %{?_smp_mflags} popd @@ -192,6 +195,10 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Fri Mar 22 2013 Orion Poplawski - 0.9.3-6.cvs20130321 +- Update cvs patch to current cvs +- Add patch to use python 2 with cmake + * Wed Mar 20 2013 Orion Poplawski - 0.9.3-5 - Add patch to handle netcdf better with cmake - BR netcdf-devel instead of netcdf-cxx-devel