summaryrefslogtreecommitdiffstats
path: root/catalogmgr/ops.cc
diff options
context:
space:
mode:
Diffstat (limited to 'catalogmgr/ops.cc')
-rw-r--r--catalogmgr/ops.cc3803
1 files changed, 3803 insertions, 0 deletions
diff --git a/catalogmgr/ops.cc b/catalogmgr/ops.cc
new file mode 100644
index 0000000..ee6ad24
--- /dev/null
+++ b/catalogmgr/ops.cc
@@ -0,0 +1,3803 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community 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 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+*/
+static const char rcsid[] = "@(#)catalogif,ops.cc: $Header: /home/rasdev/CVS-repository/rasdaman/catalogmgr/ops.cc,v 1.67 2003/12/20 23:41:27 rasdev Exp $";
+
+#include <limits.h>
+#include <values.h>
+#include <string.h> // memcpy()
+#include <malloc.h> // malloc()
+#include "ops.hh"
+#include "relcatalogif/alltypes.hh"
+#include "typefactory.hh"
+#include "raslib/point.hh"
+
+//-----------------------------------------------
+// getUnaryOp
+//-----------------------------------------------
+UnaryOp* Ops::getUnaryOp(Ops::OpType op, const BaseType* resType, const BaseType* opType, unsigned int resOff, unsigned int opOff) {
+
+#ifndef NO_OPT_OPS
+/////////////////////////////////////////////
+ if(resType->getType() == opType->getType() && resType->getSize() == 1 && resType->getType() != STRUCT) {
+ switch(op) {
+ case Ops::OP_IDENTITY:
+ return new OpIDENTITYChar(resType, opType, resOff, opOff );
+ }
+ }
+ if(resType->getType() == opType->getType() && resType->getSize() == 2 && resType->getType() != STRUCT) {
+ switch(op) {
+ case Ops::OP_IDENTITY:
+ return new OpIDENTITYShort(resType, opType, resOff, opOff );
+ }
+ }
+ if(resType->getType() == opType->getType() && resType->getSize() == 4 && resType->getType() != STRUCT ) {
+ switch(op) {
+ case Ops::OP_IDENTITY:
+ return new OpIDENTITYLong(resType, opType, resOff, opOff );
+ }
+ }
+/////////////////////////////////////////////
+#endif
+
+ // cast operations
+ if(op > Ops::OP_CAST_BEGIN && op < Ops::OP_CAST_END) {
+ if(opType->getType() < STRUCT)
+ return new OpCAST(resType, opType, resOff, opOff );
+
+ else if(opType->getType() == STRUCT)
+ return new OpUnaryStruct(resType, opType, op, resOff, opOff);
+
+ else
+ return 0;
+ }
+
+ // all Char
+ if( resType->getType() == BOOLTYPE && opType->getType() == BOOLTYPE ) {
+ switch(op) {
+ case Ops::OP_NOT:
+ return new OpNOTBool(resType, opType, resOff, opOff );
+ }
+ }
+ if((resType->getType() >= ULONG && resType->getType() <= BOOLTYPE) && (opType->getType() >= ULONG &&
+ opType->getType() <= OCTET)) {
+
+ switch(op) {
+ case Ops::OP_NOT:
+ return new OpNOTCULong(resType, opType, resOff, opOff );
+ case Ops::OP_IDENTITY:
+ return new OpIDENTITYCULong(resType, opType, resOff, opOff );
+ default:
+ return 0;
+ }
+ }
+ // result is LONG, SHORT or OCTET and the only operand between ULONG and OCTET
+ if((resType->getType() == LONG || resType->getType() == SHORT || resType->getType() == OCTET) &&
+ (opType->getType() >= ULONG && opType->getType() <= OCTET) ) {
+
+ switch(op) {
+ case Ops::OP_NOT:
+ return new OpNOTCLong(resType, opType, resOff, opOff );
+ case Ops::OP_IDENTITY:
+ return new OpIDENTITYCLong(resType, opType, resOff, opOff );
+ default:
+ return 0;
+ }
+ }
+
+ // result is COMPELEXTYPE1 or COMPLEXTYPE2
+ if(resType->getType() == COMPLEXTYPE1 && opType->getType() == COMPLEXTYPE1 || // remember && has precedence over ||
+ resType->getType() == COMPLEXTYPE2 && opType->getType() == COMPLEXTYPE2 )
+ return new OpIDENTITYComplex(resType, opType, resOff, opOff );
+
+
+
+ // result is FLOAT or DOUBLE and the only operand between ULONG and FLOAT
+ if(resType->getType() == FLOAT || resType->getType() == DOUBLE && opType->getType() >= ULONG && opType->getType() <= FLOAT) {
+
+ switch(op) {
+ case Ops::OP_IDENTITY:
+ return new OpIDENTITYCDouble(resType, opType, resOff, opOff );
+
+ case Ops::OP_SQRT:
+ return new OpSQRTCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_ABS:
+ return new OpABSCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_EXP:
+ return new OpEXPCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_LOG:
+ return new OpLOGCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_LN:
+ return new OpLNCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_SIN:
+ return new OpSINCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_COS:
+ return new OpCOSCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_TAN:
+ return new OpTANCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_SINH:
+ return new OpSINHCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_COSH:
+ return new OpCOSHCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_TANH:
+ return new OpTANHCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_ARCSIN:
+ return new OpARCSINCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_ARCCOS:
+ return new OpARCCOSCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_ARCTAN:
+ return new OpARCTANCDouble(resType, opType, resOff, opOff);
+
+ case Ops::OP_REALPART:
+ return new OpRealPart(resType, opType, resOff, opOff);
+ case Ops::OP_IMAGINARPART:
+ return new OpImaginarPart(resType, opType, resOff, opOff);
+
+ default:
+ return 0;
+ }
+ }
+
+ // retriving real or imaginar parts of a complex argument
+ if(resType->getType() == DOUBLE && (opType->getType() == COMPLEXTYPE1 || opType->getType() == COMPLEXTYPE2)) {
+ switch(op) {
+ case Ops::OP_REALPART:
+ return new OpRealPart(resType, opType, resOff, opOff);
+
+ case Ops::OP_IMAGINARPART:
+ return new OpImaginarPart(resType, opType, resOff, opOff);
+
+ default:
+ return 0;
+ }
+ }
+
+ if(resType->getType() == COMPLEXTYPE1 && opType->getType() == COMPLEXTYPE1 || // remember && has precedence over ||
+ resType->getType() == COMPLEXTYPE2 && opType->getType() == COMPLEXTYPE2 )
+ return new OpIDENTITYComplex(resType, opType, resOff, opOff );
+
+ if( resType->getType() == STRUCT && resType->compatibleWith(opType) ) {
+
+#ifndef NO_OPT_IDENTITY_STRUCT
+/////////////////////////////
+ switch(op) {
+ case Ops::OP_IDENTITY:
+ return new OpIDENTITYStruct(resType, opType, resOff, opOff );
+ default:
+/////////////////////////////
+#endif
+ return new OpUnaryStruct( resType, opType, op, resOff, opOff );
+
+#ifndef NO_OPT_IDENTITY_STRUCT
+/////////////////////////////
+ }
+/////////////////////////////
+#endif
+
+ }
+ return 0;
+}
+
+BinaryOp*
+Ops::getBinaryOp( Ops::OpType op, const BaseType* resType, const BaseType* op1Type,
+ const BaseType* op2Type, unsigned int resOff,
+ unsigned int op1Off, unsigned int op2Off )
+{
+// if this flag is set, optimized operation execution for Char
+// is turned off.
+#ifndef NO_OPT_OPS
+ // all Char
+ if( resType->getType() == CHAR && op1Type->getType() == CHAR &&
+ op2Type->getType() == CHAR ) {
+ switch(op) {
+ case Ops::OP_PLUS:
+ return new OpPLUSChar(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_MINUS:
+ return new OpMINUSChar(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_DIV:
+ return new OpDIVChar(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_MULT:
+ return new OpMULTChar(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ }
+ }
+#endif
+ if ((resType->getType() == op1Type->getType()) && (resType->getType() == op2Type->getType()) && (op == Ops::OP_OVERLAY))
+ {
+ return new OpOVERLAY(resType, op1Type, op2Type, resType->getSize(), OpOVERLAY::nullPattern, resOff, op1Off, op2Off);
+ }
+
+ // all Bool
+ if( resType->getType() == BOOLTYPE && op1Type->getType() == BOOLTYPE &&
+ op2Type->getType() == BOOLTYPE ) {
+ switch(op) {
+ case Ops::OP_AND:
+ return new OpANDBool(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_OR:
+ return new OpORBool(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_XOR:
+ return new OpXORBool(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ }
+ }
+ // result is unsigned integer
+ if( (resType->getType() >= ULONG && resType->getType() <= BOOLTYPE) &&
+ (op1Type->getType() >= ULONG && op1Type->getType() <= OCTET) &&
+ (op2Type->getType() >= ULONG && op2Type->getType() <= OCTET) ) {
+ switch(op) {
+ case Ops::OP_PLUS:
+ return new OpPLUSCULong(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_MINUS:
+ return new OpMINUSCULong(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_DIV:
+ return new OpDIVCULong(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_MULT:
+ return new OpMULTCULong(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_AND:
+ return new OpANDCULong(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_OR:
+ return new OpORCULong(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ case Ops::OP_XOR:
+ return new OpXORCULong(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ }
+ }
+ // result is signed integer
+ if( (resType->getType() == LONG || resType->getType() == SHORT ||
+ resType->getType() == OCTET) &&
+ (op1Type->getType() >= ULONG && op1Type->getType() <= OCTET) &&
+ (op2Type->getType() >= ULONG && op2Type->getType() <= OCTET) ) {
+ switch(op) {
+ case Ops::OP_PLUS:
+ return new OpPLUSCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_MINUS:
+ return new OpMINUSCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_DIV:
+ return new OpDIVCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_MULT:
+ return new OpMULTCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_AND:
+ return new OpANDCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_OR:
+ return new OpANDCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_XOR:
+ return new OpANDCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ }
+ }
+ // result is float or double
+ if( (resType->getType() == FLOAT || resType->getType() == DOUBLE) &&
+ (op1Type->getType() >= ULONG && op1Type->getType() <= FLOAT) &&
+ (op2Type->getType() >= ULONG && op2Type->getType() <= FLOAT) ) {
+ switch(op) {
+ case Ops::OP_PLUS:
+ return new OpPLUSCDouble(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_MINUS:
+ return new OpMINUSCDouble(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_DIV:
+ return new OpDIVCDouble(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_MULT:
+ return new OpMULTCDouble(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ }
+ }
+
+
+//*************************************************************************************
+// *** COMPLEXTYPE ***
+//************************************************************************************
+
+ // result is complex
+ if(resType->getType() == COMPLEXTYPE1 || resType->getType() == COMPLEXTYPE2) {
+ switch(op) {
+
+ case Ops::OP_PLUS:
+ if(op1Type->getType() < COMPLEXTYPE1)
+ return new OpPLUSComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off, OpPLUSComplex::FIRST);
+ else if(op2Type->getType() < COMPLEXTYPE1)
+ return new OpPLUSComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off, OpPLUSComplex::SECOND);
+ else
+ return new OpPLUSComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+
+ case Ops::OP_MINUS:
+ if(op1Type->getType() < COMPLEXTYPE1)
+ return new OpMINUSComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off, OpMINUSComplex::FIRST);
+ else if(op2Type->getType() < COMPLEXTYPE1)
+ return new OpMINUSComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off, OpMINUSComplex::SECOND);
+ else
+ return new OpMINUSComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+
+ case Ops::OP_DIV:
+ if(op1Type->getType() < COMPLEXTYPE1)
+ return new OpDIVComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off, OpDIVComplex::FIRST);
+ else if(op2Type->getType() < COMPLEXTYPE1)
+ return new OpDIVComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off, OpDIVComplex::SECOND);
+ else
+ return new OpDIVComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+
+ case Ops::OP_MULT:
+ if(op1Type->getType() < COMPLEXTYPE1)
+ return new OpMULTComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off, OpMULTComplex::FIRST);
+ else if(op2Type->getType() < COMPLEXTYPE1)
+ return new OpMULTComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off, OpMULTComplex::SECOND);
+ else
+ return new OpMULTComplex(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+ }
+ }
+
+//*************************************************************************************
+
+
+#ifndef NO_OPT_OPS
+ // result is bool, operands are Chars
+ if( (resType->getType() == BOOLTYPE) && (op1Type->getType() == CHAR) &&
+ (op2Type->getType() == CHAR) ) {
+ switch(op) {
+ case Ops::OP_EQUAL:
+ return new OpEQUALChar(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_LESS:
+ return new OpLESSChar(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_LESSEQUAL:
+ return new OpLESSEQUALChar(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_NOTEQUAL:
+ return new OpNOTEQUALChar(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_GREATER:
+ return new OpGREATERChar(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_GREATEREQUAL:
+ return new OpGREATEREQUALChar(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ }
+ }
+#endif
+ // result is bool
+ if( (resType->getType() == BOOLTYPE) &&
+ (op1Type->getType() >= ULONG && op1Type->getType() <= BOOLTYPE) &&
+ (op2Type->getType() >= ULONG && op2Type->getType() <= BOOLTYPE) ) {
+ switch(op) {
+ case Ops::OP_EQUAL:
+ return new OpEQUALCCharCULong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_LESS:
+ return new OpLESSCCharCULong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_LESSEQUAL:
+ return new OpLESSEQUALCCharCULong(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_NOTEQUAL:
+ return new OpNOTEQUALCCharCULong(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_GREATER:
+ return new OpGREATERCCharCULong(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_GREATEREQUAL:
+ return new OpGREATEREQUALCCharCULong(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ }
+ }
+ if( (resType->getType() == BOOLTYPE) &&
+ (op1Type->getType() >= ULONG && op1Type->getType() <= OCTET ) &&
+ (op2Type->getType() >= ULONG && op2Type->getType() <= OCTET ) ) {
+ switch(op) {
+ case Ops::OP_EQUAL:
+ return new OpEQUALCCharCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_LESS:
+ return new OpLESSCCharCLong(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_LESSEQUAL:
+ return new OpLESSEQUALCCharCLong(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_NOTEQUAL:
+ return new OpNOTEQUALCCharCLong(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_GREATER:
+ return new OpGREATERCCharCLong(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_GREATEREQUAL:
+ return new OpGREATEREQUALCCharCLong(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_BIT:
+ return new OpBIT(resType, op1Type, op2Type, resOff, op1Off, op2Off);
+
+ }
+ }
+ if( (resType->getType() == BOOLTYPE) &&
+ (op1Type->getType() >= ULONG && op1Type->getType() <= FLOAT ) &&
+ (op2Type->getType() >= ULONG && op2Type->getType() <= FLOAT ) ) {
+ switch(op) {
+ case Ops::OP_EQUAL:
+ return new OpEQUALCCharCDouble(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_LESS:
+ return new OpLESSCCharCDouble(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_LESSEQUAL:
+ return new OpLESSEQUALCCharCDouble(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_NOTEQUAL:
+ return new OpNOTEQUALCCharCDouble(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_GREATER:
+ return new OpGREATERCCharCDouble(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ case Ops::OP_GREATEREQUAL:
+ return new OpGREATEREQUALCCharCDouble(resType, op1Type, op2Type, resOff,
+ op1Off, op2Off);
+ }
+ }
+ // comparison of structs
+ if( (resType->getType() == BOOLTYPE) &&
+ (op1Type->getType() >= STRUCT && op1Type->getType() <= CLASSTYPE ) &&
+ (op1Type->compatibleWith(op2Type)) ) {
+ switch(op) {
+ case Ops::OP_EQUAL:
+ return new OpEQUALStruct(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ case Ops::OP_NOTEQUAL:
+ return new OpNOTEQUALStruct(resType, op1Type, op2Type, resOff, op1Off,
+ op2Off);
+ }
+ }
+ // result is Struct, two operands are structs
+ if( resType->getType() == STRUCT && op1Type->getType() == STRUCT &&
+ op2Type->getType() == STRUCT ) {
+
+
+ if(op >= OP_MINUS && op <= OP_XOR && isApplicableOnStruct(op, op1Type) &&
+ resType->compatibleWith(op1Type) && resType->compatibleWith(op2Type)) {
+ return new OpBinaryStruct( resType, op, resOff, op1Off, op2Off);
+ }
+ else
+ return 0;
+ }
+ // result is Struct, first operand is struct
+ if( resType->getType() == STRUCT && op1Type->getType() == STRUCT ) {
+ if(op >= OP_MINUS && op <= OP_XOR &&
+ isApplicableOnStructConst(op, op1Type, op2Type)) {
+ return new OpBinaryStructConst(
+ resType, op1Type, op2Type,
+ op,
+ resOff, op1Off, op2Off
+ );
+ }
+ else
+ return 0;
+ }
+ // result is Struct, second operand is struct
+ if( resType->getType() == STRUCT && op2Type->getType() == STRUCT ) {
+ if(op >= OP_MINUS && op <= OP_XOR &&
+ isApplicableOnStructConst(op, op2Type, op1Type))
+ return new OpBinaryConstStruct(
+ resType, op1Type, op2Type,
+ op,
+ resOff, op1Off, op2Off
+ );
+ else
+ return 0;
+ }
+ return 0;
+}
+
+
+//-----------------------------------------------------------------
+// getCondenseOp
+//-----------------------------------------------------------------
+
+CondenseOp*
+Ops::getCondenseOp(Ops::OpType op, const BaseType* resType, const BaseType* opType, unsigned int resOff, unsigned int opOff) {
+ if(resType->getType() == BOOLTYPE) {
+ switch(op) {
+ case Ops::OP_SOME:
+ return new OpSOMECChar(resType, opType, resOff, opOff);
+ case Ops::OP_ALL:
+ return new OpALLCChar(resType, opType, resOff, opOff);
+ }
+ }
+
+ else if( resType->getType() == ULONG && opType->getType() == BOOLTYPE ) {
+ switch(op) {
+ case Ops::OP_COUNT:
+ return new OpCOUNTCChar(resType, opType, resOff, opOff);
+ case Ops::OP_SUM:
+ return new OpSUMCULong(resType, opType, resOff, opOff);
+ }
+ }
+
+ else if((resType->getType() >= ULONG && resType->getType() <= BOOLTYPE) &&
+ (opType->getType() >= ULONG && opType->getType() <= BOOLTYPE)) {
+ switch(op) {
+ case Ops::OP_MAX:
+ return new OpMAXCULong(resType, opType, resOff, opOff);
+ case Ops::OP_MIN:
+ return new OpMINCULong(resType, opType, resOff, opOff);
+ case Ops::OP_SUM:
+ return new OpSUMCULong(resType, opType, resOff, opOff);
+ }
+ }
+
+ else if((resType->getType() == LONG || resType->getType() == SHORT ||
+ resType->getType() == OCTET) && (opType->getType() >= ULONG && opType->getType() <= OCTET) ) {
+ switch(op) {
+ case Ops::OP_MAX:
+ return new OpMAXCLong(resType, opType, resOff, opOff);
+ case Ops::OP_MIN:
+ return new OpMINCLong(resType, opType, resOff, opOff);
+ case Ops::OP_SUM:
+ return new OpSUMCLong(resType, opType, resOff, opOff);
+ }
+ }
+ else if((resType->getType() == FLOAT || resType->getType() == DOUBLE ) &&
+ (opType->getType() >= ULONG && opType->getType() <= FLOAT) ) {
+ switch(op) {
+ case Ops::OP_MAX:
+ return new OpMAXCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_MIN:
+ return new OpMINCDouble(resType, opType, resOff, opOff);
+ case Ops::OP_SUM:
+ return new OpSUMCDouble(resType, opType, resOff, opOff);
+ }
+ }
+ else if( resType->getType() == STRUCT)
+ // res and op are structs with same structure.
+ return new OpCondenseStruct( resType, opType, op, resOff, opOff );
+
+ return 0;
+}
+
+
+CondenseOp*
+Ops::getCondenseOp( Ops::OpType op, const BaseType* resType, char* newAccu,
+ const BaseType* opType, unsigned int resOff, unsigned int opOff )
+{
+ if(resType->getType() == BOOLTYPE) {
+ switch(op) {
+ case Ops::OP_SOME:
+ return new OpSOMECChar(resType, newAccu, opType, resOff, opOff);
+ case Ops::OP_ALL:
+ return new OpALLCChar(resType, newAccu, opType, resOff, opOff);
+ }
+ }
+ else if( resType->getType() == ULONG && opType->getType() == BOOLTYPE ) {
+ switch(op) {
+ case Ops::OP_COUNT:
+ return new OpCOUNTCChar(resType, newAccu, opType, resOff, opOff);
+ }
+ }
+ else if( (resType->getType() >= ULONG && resType->getType() <= BOOLTYPE) &&
+ (opType->getType() >= ULONG && opType->getType() <= BOOLTYPE) ) {
+ switch(op) {
+ case Ops::OP_MAX:
+ return new OpMAXCULong(resType, newAccu, opType, resOff, opOff);
+ case Ops::OP_MIN:
+ return new OpMINCULong(resType, newAccu, opType, resOff, opOff);
+ case Ops::OP_SUM:
+ return new OpSUMCULong(resType, newAccu, opType, resOff, opOff);
+ }
+ }
+ else if( (resType->getType() == LONG || resType->getType() == SHORT ||
+ resType->getType() == OCTET) &&
+ (opType->getType() >= ULONG && opType->getType() <= OCTET) ) {
+ switch(op) {
+ case Ops::OP_MAX:
+ return new OpMAXCLong(resType, newAccu, opType, resOff, opOff);
+ case Ops::OP_MIN:
+ return new OpMINCLong(resType, newAccu, opType, resOff, opOff);
+ case Ops::OP_SUM:
+ return new OpSUMCLong(resType, newAccu, opType, resOff, opOff);
+ }
+ }
+ else if( (resType->getType() == FLOAT || resType->getType() == DOUBLE ) &&
+ (opType->getType() >= ULONG && opType->getType() <= FLOAT) ) {
+ switch(op) {
+ case Ops::OP_MAX:
+ return new OpMAXCDouble(resType, newAccu, opType, resOff, opOff);
+ case Ops::OP_MIN:
+ return new OpMINCDouble(resType, newAccu, opType, resOff, opOff);
+ case Ops::OP_SUM:
+ return new OpSUMCDouble(resType, newAccu, opType, resOff, opOff);
+ }
+ }
+ else if( resType->getType() == STRUCT ) {
+ // res and op are structs with same structure.
+ return new OpCondenseStruct( resType, newAccu, opType, op, resOff, opOff );
+ }
+ return 0;
+}
+
+//-----------------------------------------------
+// isApplicable
+//-----------------------------------------------
+int Ops::isApplicable(Ops::OpType op, const BaseType* op1Type, const BaseType* op2Type) {
+ UnaryOp* myUnaryOp;
+ BinaryOp* myBinaryOp;
+ CondenseOp* myCondenseOp;
+
+ const BaseType* resType;
+
+ // could be getResType( op, op1Type, op2Type ), but this
+ // introduces circular dependency between the two functions.
+ // So it is broken here.
+
+ if( op == OP_SOME || op == OP_ALL || (op >= OP_EQUAL && op <= OP_GREATEREQUAL) ) {
+ // result must be Bool
+ resType = TypeFactory::mapType("Bool");
+ }
+ else if(op == OP_COUNT)
+ resType = TypeFactory::mapType("ULong");
+
+ else if(op > OP_UFUNC_BEGIN && op < OP_UFUNC_END )
+ resType = TypeFactory::mapType("Double");
+
+ else if(op > Ops::OP_CAST_BEGIN && op < Ops::OP_CAST_END && op1Type->getType() <= FLOAT) {
+ const char *typeName[] = {
+ "Bool", "Char", "Octet", "Short", "UShort",
+ "Long", "ULong", "Float", "Double"
+ };
+ resType = TypeFactory::mapType(typeName[op - OP_CAST_BEGIN - 1]);
+ }
+
+ else if(op == OP_BIT)
+ resType = TypeFactory::mapType("Bool");
+ else if(op == OP_SUM && op1Type->getType() <= CHAR)
+ resType = TypeFactory::mapType("ULong");
+ else if(op == OP_SUM && op1Type->getType() <= OCTET)
+ resType = TypeFactory::mapType("Long");
+ else if(op == OP_SUM && op1Type->getType() <= FLOAT)
+ resType = TypeFactory::mapType("Double");
+ else if(op == OP_SUM && op1Type->getType() == COMPLEXTYPE1)
+ resType = TypeFactory::mapType("Complex1");
+ else if(op == OP_SUM && op1Type->getType() == COMPLEXTYPE2)
+ resType = TypeFactory::mapType("Complex2");
+
+ // unary operations on complex: re, im
+ else if(op == OP_REALPART || op == OP_IMAGINARPART) {
+ if(op1Type->getType() == COMPLEXTYPE1)
+ resType = TypeFactory::mapType("Float");
+ if(op1Type->getType() == COMPLEXTYPE2)
+ resType = TypeFactory::mapType("Double");
+ }
+
+ else if(op2Type == 0)
+ resType = (BaseType*)op1Type;
+
+ else if( op1Type->getType() >= STRUCT && op1Type->getType() <= CLASSTYPE )
+ // composite types must be compatible, so just take one of them as
+ // result
+ resType = (BaseType*)op1Type;
+ else if( op2Type->getType() >= STRUCT && op2Type->getType() <= CLASSTYPE )
+ // composite types must be compatible, so just take one of them as
+ // result
+ resType = (BaseType*)op2Type;
+
+
+ else if(op1Type->getType() == COMPLEXTYPE2 || op2Type->getType() == COMPLEXTYPE2)
+ // if one of the opernds is complex type and the other any atomic type
+ // the result should be complex
+ resType = TypeFactory::mapType("Complex2");
+
+ else if(op1Type->getType() == COMPLEXTYPE1 || op2Type->getType() == COMPLEXTYPE1)
+ // idem
+ resType = TypeFactory::mapType("Complex1");
+
+ else if( op >= OP_IS && op <= OP_XOR )
+ // result must be long in this case
+ resType = TypeFactory::mapType("Long");
+ else
+ // Double is the strongest type anyway
+ resType = TypeFactory::mapType("Double");
+
+ if(op == OP_OVERLAY)
+ resType = (BaseType*)op1Type;
+
+
+ // unary or condense operations
+ if(op2Type == 0) {
+ myUnaryOp = getUnaryOp(op, resType, (BaseType*)op1Type);
+ if(myUnaryOp != 0) {
+ delete myUnaryOp;
+ return 1; // found an unary op
+ }
+ myCondenseOp = getCondenseOp(op, (BaseType*)resType, (BaseType*)op1Type);
+ if(myCondenseOp != 0) {
+ delete myCondenseOp;
+ return 1; // found a condense op
+ }
+ else
+ return 0; // found neither
+ }
+ else {
+ myBinaryOp = getBinaryOp(op, resType, (BaseType*)op1Type, (BaseType*)op2Type);
+ if(myBinaryOp != 0) {
+ delete myBinaryOp;
+ return 1;
+
+ }
+ else
+ return 0;
+ }
+}
+
+
+//-----------------------------------------------
+// getResultType
+//-----------------------------------------------
+const BaseType* Ops::getResultType(Ops::OpType op, const BaseType* op1, const BaseType* op2) {
+
+ // operations between composite types defined only on compatible types
+ if(op == OP_OVERLAY)
+ {
+ if ((op1->getType() == STRUCT) || (op2->getType() == STRUCT))
+ {
+ if (op1->compatibleWith(op2))
+ {
+ return op1;
+ }
+ else {
+ return NULL;
+ }
+ }
+ if (op1->getType() == op2->getType())
+ {
+ return op1;
+ }
+ return NULL;
+ }
+
+ // operation BIT returns bool or struct {bool, ...}
+ if(op == OP_BIT) {
+ if(op1->getType() == STRUCT) {
+ StructType* resStructType = new StructType;
+ TypeFactory::addTempType(resStructType);
+
+ StructType* opStructType = (StructType* )op1;
+
+ for(int i = 0; i < opStructType->getNumElems(); ++i) {
+ const BaseType* resType = getResultType(op, opStructType->getElemType(i), op2);
+
+ if(!resType)
+ return 0;
+
+ resStructType->addElement(opStructType->getElemName(i), resType);
+ }
+
+ return (BaseType *) resStructType;
+ }
+
+ // integral types
+ else if(op1->getType() <= OCTET)
+ return TypeFactory::mapType("Bool");
+
+ else
+ return 0;
+ }
+
+ // operation not even applicable, so no result type
+ if(!isApplicable(op, op1, op2)) {
+ return 0;
+ }
+
+ // the condense operation COUNT always returns an unsigned long
+ if( op == Ops::OP_COUNT )
+ return TypeFactory::mapType("ULong");
+ // SQRT returns DOUBLE
+
+
+ if( op > Ops::OP_UFUNC_BEGIN && op < Ops::OP_UFUNC_END )
+ return TypeFactory::mapType("Double");
+
+ if(op > Ops::OP_CAST_BEGIN && op < Ops::OP_CAST_END) {
+ if(op1->getType() < STRUCT) {
+ const char *typeName[] = {
+ "Bool", "Char", "Octet", "Short", "UShort",
+ "Long", "ULong", "Float", "Double"
+ };
+ return TypeFactory::mapType(typeName[op - OP_CAST_BEGIN - 1]);
+ }
+
+ else if(op1->getType() == STRUCT) {
+ StructType* resStructType = new StructType;
+ TypeFactory::addTempType(resStructType);
+ StructType* opStructType = (StructType* )op1;
+
+ for(int i = 0; i < opStructType->getNumElems(); ++i) {
+ const BaseType* resType = getResultType(op, opStructType->getElemType(i));
+ if(!resType)
+ return 0;
+
+ resStructType->addElement(opStructType->getElemName(i), resType);
+ }
+
+ return (BaseType *)resStructType;
+ }
+
+ else
+ return 0;
+
+ }
+
+ // the condense operation ADD_CELLS returns maximal type
+ // (i.e. long/ulong or double)
+ if(!op2 && op == Ops::OP_SUM) {
+ if(op1->getType() <= BOOLTYPE)
+ return TypeFactory::mapType("ULong");
+
+ if(op1->getType() <= OCTET)
+ return TypeFactory::mapType("Long");
+
+ else if(op1->getType() <= FLOAT)
+ return TypeFactory::mapType("Double");
+
+ else if(op1->getType() == COMPLEXTYPE1)
+ return TypeFactory::mapType("Complex1");
+
+ else if(op1->getType() == COMPLEXTYPE2)
+ return TypeFactory::mapType("Complex2");
+
+ else if(op1->getType() == STRUCT) {
+ StructType* resStructType = new StructType;
+ TypeFactory::addTempType(resStructType);
+ StructType* opStructType = (StructType* )op1;
+
+ for(int i = 0; i < opStructType->getNumElems(); ++i) {
+ const BaseType* resType = getResultType(op, opStructType->getElemType(i));
+ if(!resType)
+ return 0;
+
+ resStructType->addElement(opStructType->getElemName(i), resType);
+ }
+
+ return (BaseType *)resStructType;
+ }
+ else
+ return 0;
+ }
+
+ // some :-) unary and condense operations return the same type
+ if(op == OP_REALPART || op == OP_IMAGINARPART) {
+ if(op1->getType() == COMPLEXTYPE1)
+ return TypeFactory::mapType("Float");
+ else if(op1->getType() == COMPLEXTYPE2)
+ return TypeFactory::mapType("Double");
+ }
+ if( op2 == 0 )
+ return (BaseType*)op1;
+ // operations between composite types defined only on compatible types
+ if( op1->getType() >= STRUCT && op1->getType() <= CLASSTYPE ) {
+ if( op == OP_EQUAL || op == OP_NOTEQUAL )
+ return TypeFactory::mapType("Bool");
+ else {
+ if(op1->getType() == STRUCT && op2->getType() <= FLOAT) {
+
+ StructType* resStructType = new StructType;
+ TypeFactory::addTempType(resStructType);
+ StructType* opStructType = (StructType* )op1;
+
+ for(int i = 0; i < opStructType->getNumElems(); ++i) {
+ const BaseType* resType = getResultType(op, opStructType->getElemType(i), op2);
+ if(!resType)
+ return 0;
+
+ resStructType->addElement(opStructType->getElemName(i), resType);
+ }
+
+ return (BaseType *)resStructType;
+ }
+ else
+ return (BaseType*)op1;
+ }
+ }
+ if( op2->getType() >= STRUCT && op2->getType() <= CLASSTYPE ) {
+
+ if(op1->getType() <= FLOAT && op2->getType() == STRUCT) {
+
+ StructType* resStructType = new StructType;
+ TypeFactory::addTempType(resStructType);
+ StructType* opStructType = (StructType* )op2;
+
+ for(int i = 0; i < opStructType->getNumElems(); ++i) {
+ const BaseType* resType = getResultType(op, op1, opStructType->getElemType(i));
+ if(!resType)
+ return 0;
+ resStructType->addElement(opStructType->getElemName(i), resType);
+ }
+
+
+ return (BaseType *)resStructType;
+ }
+ else
+ return (BaseType*)op2;
+ }
+
+ // comparison operators always return bool
+ if(op >= OP_EQUAL && op <= OP_GREATEREQUAL)
+ return TypeFactory::mapType("Bool");
+ // all the other binary functions return "strongest" type
+ // if only one of operand is signed, result also has to be signed.
+ if( isSignedType(op1) && !isSignedType(op2) ) {
+ // swap it, action is in next if clause
+ const BaseType* dummy;
+ dummy = op2;
+ op2 = op1;
+ op1 = dummy;
+ }
+ if( !isSignedType(op1) && isSignedType(op2) ) {
+ // got to get the thing with the highest precision and make sure
+ // it is signed.
+ if( op2->getType() == COMPLEXTYPE1 || op2->getType() == COMPLEXTYPE2 ||
+ op2->getType() == FLOAT || op2->getType() == DOUBLE || op2->getType() == LONG )
+ return (BaseType*)op2;
+ if( op1->getType() == USHORT )
+ return TypeFactory::mapType("Short");
+ if( op2->getType() == SHORT )
+ return (BaseType*)op2;
+ return TypeFactory::mapType("Octet");
+ }
+ // return the stronger type
+ if(op1->getType() == COMPLEXTYPE2 || op2->getType() == COMPLEXTYPE2)
+ return TypeFactory::mapType("Complex2");
+ if(op1->getType() == COMPLEXTYPE1 || op2->getType() == COMPLEXTYPE1)
+ return TypeFactory::mapType("Complex1");
+ if(op1->getType() == DOUBLE || op2->getType() == DOUBLE)
+ return TypeFactory::mapType("Double");
+ if(op1->getType() == FLOAT || op2->getType() == FLOAT)
+ return TypeFactory::mapType("Float");
+ if(op1->getType() <= op2->getType())
+ return (BaseType*)op1;
+ else
+ return (BaseType*)op2;
+}
+
+int
+Ops::isApplicableOnStruct( Ops::OpType op, const BaseType* opType )
+{
+ int i = 0;
+ StructType* myStructType = (StructType*)opType;
+ int numElems = myStructType->getNumElems();
+
+ for(i = 0; i < numElems; i++) {
+ if( !isApplicable(op, myStructType->getElemType(i),
+ myStructType->getElemType(i)) )
+ return 0;
+ }
+ return 1;
+}
+
+int
+Ops::isApplicableOnStructConst( Ops::OpType op, const BaseType* op1Type,
+ const BaseType* op2Type )
+{
+ int i = 0;
+ StructType* myStructType = (StructType*)op1Type;
+ int numElems = myStructType->getNumElems();
+
+ for(i = 0; i < numElems; i++) {
+ if( !isApplicable(op, myStructType->getElemType(i), op2Type) )
+ return 0;
+ }
+ return 1;
+}
+
+int
+Ops::isSignedType( const BaseType* type )
+{
+ return ( type->getType() >= LONG && type->getType() <= COMPLEXTYPE2 );
+}
+
+int
+Ops::isCondenseOp( Ops::OpType op )
+{
+ return ( op >= OP_SOME && op <= OP_ALL );
+}
+
+int
+Ops::isUnaryOp( Ops::OpType op )
+{
+ return ( op >= OP_NOT && op <= OP_IDENTITY );
+}
+
+int
+Ops::isBinaryOp( Ops::OpType op )
+{
+ return ( op >= OP_MINUS && op <= OP_GREATEREQUAL );
+}
+
+void
+Ops::execUnaryConstOp( Ops::OpType op, const BaseType* resType,
+ const BaseType* opType, char* res,
+ const char* op1, unsigned int resOff,
+ unsigned int opOff )
+{
+ UnaryOp* myOp = Ops::getUnaryOp( op, resType, opType, resOff, opOff );
+ try
+ {
+ (*myOp)(res, op1);
+ }
+ catch(...)
+ {
+ delete myOp; // cleanup
+ throw;
+ }
+
+ delete myOp;
+}
+
+void
+Ops::execBinaryConstOp( Ops::OpType op, const BaseType* resType,
+ const BaseType* op1Type,
+ const BaseType* op2Type, char* res,
+ const char* op1, const char* op2,
+ unsigned int resOff, unsigned int op1Off,
+ unsigned int op2Off )
+{
+ BinaryOp* myOp = Ops::getBinaryOp( op, resType, op1Type, op2Type,
+ resOff, op1Off, op2Off );
+ (*myOp)(res, op1, op2);
+ delete myOp;
+}
+
+UnaryOp::UnaryOp( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : resType(newResType), opType(newOpType), resOff(newResOff), opOff(newOpOff)
+{
+}
+
+OpIDENTITYStruct::OpIDENTITYStruct( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpIDENTITYStruct::operator()( char* res, const char* op )
+{
+ memcpy( (void*)(res + resOff), (void*)(op + opOff), resType->getSize() );
+}
+
+OpNOTCULong::OpNOTCULong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpNOTCULong::operator()( char* res, const char* op )
+{
+ r_ULong longOp;
+ r_ULong longRes;
+
+ longRes = *(opType->convertToCULong(op + opOff, &longOp)) ^ 0xFFFFFFFF;
+ resType->makeFromCULong( res + resOff, &longRes);
+}
+
+OpIDENTITYCULong::OpIDENTITYCULong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpIDENTITYCULong::operator()( char* res, const char* op )
+{
+ r_ULong longOp;
+
+ // !!!! HP specific, assumes 4 Byte long and MSB..LSB
+ // byte order
+ resType->makeFromCULong( res + resOff,
+ opType->convertToCULong(op + opOff, &longOp) );
+}
+
+OpNOTCLong::OpNOTCLong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpNOTCLong::operator()( char* res, const char* op )
+{
+ r_Long longOp;
+ r_Long longRes;
+
+ longRes = *(opType->convertToCLong(op + opOff, &longOp)) ^ 0xFFFFFFFF;
+ resType->makeFromCLong( res + resOff, &longRes);
+}
+
+OpIDENTITYCLong::OpIDENTITYCLong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpIDENTITYCLong::operator()( char* res, const char* op )
+{
+ r_Long longOp;
+
+ resType->makeFromCLong( res + resOff,
+ opType->convertToCLong(op + opOff, &longOp) );
+}
+
+OpIDENTITYCDouble::OpIDENTITYCDouble( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpIDENTITYCDouble::operator()( char* res, const char* op )
+{
+ double doubleOp;
+
+ // !!!! HP specific, assumes 4 Byte double and MSB..LSB
+ // byte order
+ resType->makeFromCDouble( res + resOff,
+ opType->convertToCDouble(op + opOff, &doubleOp) );
+}
+
+OpNOTBool::OpNOTBool( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpNOTBool::operator()( char* res, const char* op )
+{
+ // special case for bools, because bitwise not is not
+ // equivalent to logical not
+ *(res + resOff) = !(*(op + opOff));
+}
+
+BinaryOp::BinaryOp( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : resType(newResType), op1Type(newOp1Type), op2Type(newOp2Type),
+ resOff(newResOff), op1Off(newOp1Off), op2Off(newOp2Off)
+{
+}
+
+void
+BinaryOp::getCondenseInit(char* init)
+{
+ init = 0;
+ // perhaps should also raise exception as operation cannot be used
+ // as condenser.
+}
+
+OpPLUSCULong::OpPLUSCULong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpPLUSCULong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_ULong longOp1 = 0;
+ r_ULong longOp2 = 0;
+ r_ULong longRes = 0;
+
+ longRes = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) +
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+ resType->makeFromCULong( res + resOff, &longRes);
+}
+
+void
+OpPLUSCULong::getCondenseInit(char* init)
+{
+ r_ULong dummy = 0;
+
+ resType->makeFromCULong(init, &dummy);
+}
+
+OpPLUSULong::OpPLUSULong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpPLUSULong::operator()( char* res, const char* op1, const char* op2 )
+{
+ cout << "Hier krachts?" << endl;
+ *(r_ULong*)(res + resOff) =
+ *(r_ULong*)(op1 + op1Off) + *(r_ULong*)(op2 + op2Off);
+}
+
+void
+OpPLUSULong::getCondenseInit(char* init)
+{
+ r_ULong dummy = 0;
+
+ resType->makeFromCULong(init, &dummy);
+}
+
+OpMINUSCULong::OpMINUSCULong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpMINUSCULong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_ULong longOp1 = 0;
+ r_ULong longOp2 = 0;
+ r_ULong longRes = 0;
+
+ longRes = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) -
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+ resType->makeFromCULong( res + resOff, &longRes);
+}
+
+OpDIVCULong::OpDIVCULong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpDIVCULong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_ULong longOp1 = 0;
+ r_ULong longOp2 = 0;
+ r_ULong longRes = 0;
+
+ op2Type->convertToCULong(op2 + op2Off, &longOp2);
+
+ if(longOp2 == 0)
+ // catch division by zero, perhaps should throw exception
+ longRes = 0;
+ else {
+ longRes = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) / longOp2;
+ }
+
+ resType->makeFromCULong( res + resOff, &longRes);
+}
+
+OpMULTCULong::OpMULTCULong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpMULTCULong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_ULong longOp1 = 0;
+ r_ULong longOp2 = 0;
+ r_ULong longRes = 0;
+
+ longRes = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) *
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+ resType->makeFromCULong( res + resOff, &longRes);
+}
+
+void
+OpMULTCULong::getCondenseInit(char* init)
+{
+ r_ULong dummy = 1;
+
+ resType->makeFromCULong(init, &dummy);
+}
+
+OpANDCULong::OpANDCULong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpANDCULong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_ULong longOp1 = 0;
+ r_ULong longOp2 = 0;
+ r_ULong longRes = 0;
+
+ longRes = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) &
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+ resType->makeFromCULong( res + resOff, &longRes);
+}
+
+void
+OpANDCULong::getCondenseInit(char* init)
+{
+ char dummy[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+ memcpy( init, dummy, resType->getSize() );
+}
+
+OpANDBool::OpANDBool( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpANDBool::operator()( char* res, const char* op1, const char* op2 )
+{
+ *(res + resOff) = (*(op1 + op1Off) && *(op2 + op2Off));
+}
+
+void
+OpANDBool::getCondenseInit(char* init)
+{
+ *init = 1;
+}
+
+OpORCULong::OpORCULong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpORCULong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_ULong longOp1 = 0;
+ r_ULong longOp2 = 0;
+ r_ULong longRes = 0;
+
+ longRes = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) |
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+ resType->makeFromCULong( res + resOff, &longRes);
+}
+
+void
+OpORCULong::getCondenseInit(char* init)
+{
+ char dummy[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ memcpy( init, dummy, resType->getSize() );
+}
+
+OpORBool::OpORBool( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpORBool::operator()( char* res, const char* op1, const char* op2 )
+{
+ *(res + resOff) = (*(op1 + op1Off) || *(op2 + op2Off));
+}
+
+void
+OpORBool::getCondenseInit(char* init)
+{
+ *init = 0;
+}
+
+OpXORCULong::OpXORCULong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpXORCULong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_ULong longOp1 = 0;
+ r_ULong longOp2 = 0;
+ r_ULong longRes = 0;
+
+ longRes = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) ^
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+ resType->makeFromCULong( res + resOff, &longRes);
+}
+
+OpXORBool::OpXORBool( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpXORBool::operator()( char* res, const char* op1, const char* op2 )
+{
+ *(res + resOff) = !(*(op1 + op1Off) == *(op2 + op2Off));
+}
+
+OpPLUSCLong::OpPLUSCLong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpPLUSCLong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_Long longOp1 = 0;
+ r_Long longOp2 = 0;
+ r_Long longRes = 0;
+
+ longRes = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) +
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+ resType->makeFromCLong( res + resOff, &longRes);
+}
+
+void
+OpPLUSCLong::getCondenseInit(char* init)
+{
+ r_Long dummy = 0;
+
+ resType->makeFromCLong(init, &dummy);
+}
+
+OpMINUSCLong::OpMINUSCLong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpMINUSCLong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_Long longOp1 = 0;
+ r_Long longOp2 = 0;
+ r_Long longRes = 0;
+
+ longRes = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) -
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+ resType->makeFromCLong( res + resOff, &longRes);
+}
+
+OpDIVCLong::OpDIVCLong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpDIVCLong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_Long longOp1 = 0;
+ r_Long longOp2 = 0;
+ r_Long longRes = 0;
+
+ op2Type->convertToCLong(op2, &longOp2);
+
+ if(longOp2 == 0)
+ // catch division by zero, perhaps should throw exception
+ longRes = 0;
+ else {
+ longRes = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) / longOp2;
+ }
+
+ resType->makeFromCLong( res + resOff, &longRes);
+}
+
+OpMULTCLong::OpMULTCLong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpMULTCLong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_Long longOp1 = 0;
+ r_Long longOp2 = 0;
+ r_Long longRes = 0;
+
+ longRes = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) *
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+ resType->makeFromCLong( res + resOff, &longRes);
+}
+
+void
+OpMULTCLong::getCondenseInit(char* init)
+{
+ r_Long dummy = 1;
+
+ resType->makeFromCLong(init, &dummy);
+}
+
+OpANDCLong::OpANDCLong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpANDCLong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_Long longOp1 = 0;
+ r_Long longOp2 = 0;
+ r_Long longRes = 0;
+
+ longRes = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) &
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+ resType->makeFromCLong( res + resOff, &longRes);
+}
+
+void
+OpANDCLong::getCondenseInit(char* init)
+{
+ char dummy[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+ memcpy( init, dummy, resType->getSize() );
+}
+
+OpORCLong::OpORCLong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpORCLong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_Long longOp1 = 0;
+ r_Long longOp2 = 0;
+ r_Long longRes = 0;
+
+ longRes = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) |
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+ resType->makeFromCLong( res + resOff, &longRes);
+}
+
+void
+OpORCLong::getCondenseInit(char* init)
+{
+ char dummy[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ memcpy( init, dummy, resType->getSize() );
+}
+
+OpXORCLong::OpXORCLong( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpXORCLong::operator()( char* res, const char* op1, const char* op2 )
+{
+ r_Long longOp1 = 0;
+ r_Long longOp2 = 0;
+ r_Long longRes = 0;
+
+ longRes = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) ^
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+ resType->makeFromCLong( res + resOff, &longRes);
+}
+
+OpPLUSCDouble::OpPLUSCDouble( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpPLUSCDouble::operator()( char* res, const char* op1, const char* op2 )
+{
+ double doubleOp1 = 0;
+ double doubleOp2 = 0;
+ double doubleRes = 0;
+
+ doubleRes = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) +
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+ resType->makeFromCDouble( res + resOff, &doubleRes);
+}
+
+void
+OpPLUSCDouble::getCondenseInit(char* init)
+{
+ double dummy = 0.0;
+
+ resType->makeFromCDouble(init, &dummy);
+}
+
+OpMINUSCDouble::OpMINUSCDouble( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpMINUSCDouble::operator()( char* res, const char* op1, const char* op2 )
+{
+ double doubleOp1 = 0;
+ double doubleOp2 = 0;
+ double doubleRes = 0;
+
+ doubleRes = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) -
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+ resType->makeFromCDouble( res + resOff, &doubleRes);
+}
+
+OpDIVCDouble::OpDIVCDouble( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpDIVCDouble::operator()( char* res, const char* op1, const char* op2 )
+{
+ double doubleOp1 = 0;
+ double doubleOp2 = 0;
+ double doubleRes = 0;
+
+ op2Type->convertToCDouble(op2, &doubleOp2);
+
+ if(doubleOp2 == 0)
+ // catch division by zero, perhaps should throw exception
+ doubleRes = 0;
+ else {
+ doubleRes = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) / doubleOp2;
+ }
+
+ resType->makeFromCDouble( res + resOff, &doubleRes);
+}
+
+OpMULTCDouble::OpMULTCDouble( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpMULTCDouble::operator()( char* res, const char* op1, const char* op2 )
+{
+ double doubleOp1 = 0;
+ double doubleOp2 = 0;
+ double doubleRes = 0;
+
+ doubleRes = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) *
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+ resType->makeFromCDouble( res + resOff, &doubleRes);
+}
+
+void
+OpMULTCDouble::getCondenseInit(char* init)
+{
+ double dummy = 1.0;
+
+ resType->makeFromCDouble(init, &dummy);
+}
+
+OpEQUALCCharCULong::OpEQUALCCharCULong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpEQUALCCharCULong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_ULong longOp1;
+ r_ULong longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) ==
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+}
+
+OpLESSCCharCULong::OpLESSCCharCULong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpLESSCCharCULong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_ULong longOp1;
+ r_ULong longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) <
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+}
+
+OpLESSEQUALCCharCULong::OpLESSEQUALCCharCULong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpLESSEQUALCCharCULong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_ULong longOp1;
+ r_ULong longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) <=
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+}
+
+OpNOTEQUALCCharCULong::OpNOTEQUALCCharCULong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpNOTEQUALCCharCULong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_ULong longOp1;
+ r_ULong longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) !=
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+}
+
+OpGREATERCCharCULong::OpGREATERCCharCULong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpGREATERCCharCULong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_ULong longOp1;
+ r_ULong longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) >
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+}
+
+OpGREATEREQUALCCharCULong::OpGREATEREQUALCCharCULong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpGREATEREQUALCCharCULong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_ULong longOp1;
+ r_ULong longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCULong(op1 + op1Off, &longOp1)) >=
+ *(op2Type->convertToCULong(op2 + op2Off, &longOp2));
+}
+
+OpEQUALCCharCLong::OpEQUALCCharCLong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpEQUALCCharCLong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_Long longOp1;
+ r_Long longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) ==
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+}
+
+OpLESSCCharCLong::OpLESSCCharCLong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpLESSCCharCLong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_Long longOp1;
+ r_Long longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) <
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+}
+
+OpLESSEQUALCCharCLong::OpLESSEQUALCCharCLong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpLESSEQUALCCharCLong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_Long longOp1;
+ r_Long longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) <=
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+}
+
+OpNOTEQUALCCharCLong::OpNOTEQUALCCharCLong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpNOTEQUALCCharCLong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_Long longOp1;
+ r_Long longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) !=
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+}
+
+OpGREATERCCharCLong::OpGREATERCCharCLong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpGREATERCCharCLong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_Long longOp1;
+ r_Long longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) >
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+}
+
+OpGREATEREQUALCCharCLong::OpGREATEREQUALCCharCLong( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpGREATEREQUALCCharCLong::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ r_Long longOp1;
+ r_Long longOp2;
+
+ *(res + resOff) = *(op1Type->convertToCLong(op1 + op1Off, &longOp1)) >=
+ *(op2Type->convertToCLong(op2 + op2Off, &longOp2));
+}
+
+OpEQUALCCharCDouble::OpEQUALCCharCDouble( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpEQUALCCharCDouble::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ double doubleOp1;
+ double doubleOp2;
+
+ *(res + resOff) = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) ==
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+}
+
+OpLESSCCharCDouble::OpLESSCCharCDouble( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpLESSCCharCDouble::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ double doubleOp1;
+ double doubleOp2;
+
+ *(res + resOff) = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) <
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+}
+
+OpLESSEQUALCCharCDouble::OpLESSEQUALCCharCDouble( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpLESSEQUALCCharCDouble::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ double doubleOp1;
+ double doubleOp2;
+
+ *(res + resOff) = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) <=
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+}
+
+OpNOTEQUALCCharCDouble::OpNOTEQUALCCharCDouble( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpNOTEQUALCCharCDouble::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ double doubleOp1;
+ double doubleOp2;
+
+ *(res + resOff) = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) !=
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+}
+
+OpGREATERCCharCDouble::OpGREATERCCharCDouble( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpGREATERCCharCDouble::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ double doubleOp1;
+ double doubleOp2;
+
+ *(res + resOff) = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) >
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+}
+
+OpGREATEREQUALCCharCDouble::OpGREATEREQUALCCharCDouble( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpGREATEREQUALCCharCDouble::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ double doubleOp1;
+ double doubleOp2;
+
+ *(res + resOff) = *(op1Type->convertToCDouble(op1 + op1Off, &doubleOp1)) >=
+ *(op2Type->convertToCDouble(op2 + op2Off, &doubleOp2));
+}
+
+CondenseOp::CondenseOp( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : resType(newResType), opType(newOpType), resOff(newResOff), opOff(newOpOff),
+ accu(0)
+{
+}
+
+CondenseOp::CondenseOp( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : resType(newResType), opType(newOpType), resOff(newResOff), opOff(newOpOff)
+{
+ accu = new char[resType->getSize()];
+ memcpy(accu, newAccu, resType->getSize());
+}
+
+char*
+CondenseOp::getAccuVal()
+{
+ return accu;
+}
+
+CondenseOp::~CondenseOp()
+{
+ delete [] accu;
+}
+
+
+OpSOMECChar::OpSOMECChar( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ // initialising with neutral value
+ accu = new char[1];
+ // result is always char
+ *accu = 0;
+}
+
+OpSOMECChar::OpSOMECChar( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpSOMECChar::operator()( const char* op, char* init )
+{
+ *(unsigned char*)(init + resOff) = *(unsigned char*)(init + resOff) || *(unsigned char*)(op + opOff);
+ return init;
+}
+
+char*
+OpSOMECChar::operator()( const char* op )
+{
+ *(unsigned char*)(accu + resOff) = *(unsigned char*)(accu + resOff) || *(unsigned char*)(op + opOff);
+ return accu;
+}
+
+OpALLCChar::OpALLCChar( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ // initialising with neutral value
+ accu = new char[1];
+ // result is always char
+ *accu = 1;
+}
+
+OpALLCChar::OpALLCChar( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpALLCChar::operator()( const char* op, char* init )
+{
+ *(unsigned char*)(init + resOff) = *(unsigned char*)(init + resOff) &&
+ *(unsigned char*)(op + opOff);
+ return init;
+}
+
+char*
+OpALLCChar::operator()( const char* op )
+{
+ *(unsigned char*)(accu + resOff) = *(unsigned char*)(accu + resOff) &&
+ *(unsigned char*)(op + opOff);
+ return accu;
+}
+
+OpCOUNTCChar::OpCOUNTCChar( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ // initialising with neutral value
+ accu = new char[4];
+ // result is always r_ULong
+ *(r_ULong*)accu = 0;
+
+}
+
+OpCOUNTCChar::OpCOUNTCChar( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpCOUNTCChar::operator()( const char* op, char* init )
+{
+ *(r_ULong*)(init + resOff) = *(r_ULong*)(init + resOff) +
+ *(unsigned char*)(op + opOff);
+ return init;
+}
+
+char*
+OpCOUNTCChar::operator()( const char* op )
+{
+ *(r_ULong*)(accu + resOff) = *(r_ULong*)(accu + resOff) +
+ *(unsigned char*)(op + opOff);
+ return accu;
+}
+
+OpMAXCULong::OpMAXCULong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ r_ULong myVal = 0;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ resType->makeFromCULong(accu, &myVal);
+}
+
+OpMAXCULong::OpMAXCULong( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpMAXCULong::operator()( const char* op, char* init )
+{
+ r_ULong longOp = 0;
+ r_ULong longRes = 0;
+
+ longOp = *(opType->convertToCULong(op + opOff, &longOp));
+ longRes = *(resType->convertToCULong(init + resOff, &longRes));
+
+ if(longOp > longRes) {
+ resType->makeFromCULong(init + resOff, &longOp);
+ }
+
+ return init;
+}
+
+char*
+OpMAXCULong::operator()( const char* op )
+{
+ return OpMAXCULong::operator()(op, accu);
+}
+
+OpMAXCLong::OpMAXCLong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ r_Long myVal = INT_MIN;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ resType->makeFromCLong(accu, &myVal);
+}
+
+OpMAXCLong::OpMAXCLong( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpMAXCLong::operator()( const char* op, char* init )
+{
+ r_Long longOp = 0;
+ r_Long longRes = 0;
+
+ longOp = *(opType->convertToCLong(op + opOff, &longOp));
+ longRes = *(resType->convertToCLong(init + resOff, &longRes));
+
+ if(longOp > longRes) {
+ resType->makeFromCLong(init + resOff, &longOp);
+ }
+
+ return init;
+}
+
+char*
+OpMAXCLong::operator()( const char* op )
+{
+ return OpMAXCLong::operator()(op, accu);
+}
+
+OpMAXCDouble::OpMAXCDouble( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ double myVal = (-1.0)*DBL_MAX;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ // make sure accu contains a legal float
+ memset(accu, 0, resType->getSize());
+ resType->makeFromCDouble(accu, &myVal);
+}
+
+OpMAXCDouble::OpMAXCDouble( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpMAXCDouble::operator()( const char* op, char* init )
+{
+ double longOp = 0;
+ double longRes = 0;
+
+ longOp = *(opType->convertToCDouble(op + opOff, &longOp));
+ longRes = *(resType->convertToCDouble(init + resOff, &longRes));
+
+ if(longOp > longRes) {
+ resType->makeFromCDouble(init + resOff, &longOp);
+ }
+
+ return init;
+}
+
+char*
+OpMAXCDouble::operator()( const char* op )
+{
+ return OpMAXCDouble::operator()(op, accu);
+}
+
+OpMINCULong::OpMINCULong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ r_ULong myVal = UINT_MAX;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ resType->makeFromCULong(accu, &myVal);
+}
+
+OpMINCULong::OpMINCULong( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpMINCULong::operator()( const char* op, char* init )
+{
+ r_ULong longOp = 0;
+ r_ULong longRes = 0;
+
+ longOp = *(opType->convertToCULong(op + opOff, &longOp));
+ longRes = *(resType->convertToCULong(init + resOff, &longRes));
+
+ if(longOp < longRes) {
+ resType->makeFromCULong(init + resOff, &longOp);
+ }
+
+ return init;
+}
+
+char*
+OpMINCULong::operator()( const char* op )
+{
+ return OpMINCULong::operator()(op, accu);
+}
+
+OpMINCLong::OpMINCLong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ r_Long myVal = INT_MAX;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ resType->makeFromCLong(accu, &myVal);
+}
+
+OpMINCLong::OpMINCLong( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpMINCLong::operator()( const char* op, char* init )
+{
+ r_Long longOp = 0;
+ r_Long longRes = 0;
+
+ longOp = *(opType->convertToCLong(op + opOff, &longOp));
+ longRes = *(resType->convertToCLong(init + resOff, &longRes));
+
+ if(longOp < longRes) {
+ resType->makeFromCLong(init + resOff, &longOp);
+ }
+
+ return init;
+}
+
+char*
+OpMINCLong::operator()( const char* op )
+{
+ return OpMINCLong::operator()(op, accu);
+}
+
+OpMINCDouble::OpMINCDouble( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ double myVal = DBL_MAX;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ // make sure accu contains a legal float
+ memset(accu, 0, resType->getSize());
+ resType->makeFromCDouble(accu, &myVal);
+}
+
+
+OpMINCDouble::OpMINCDouble( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpMINCDouble::operator()( const char* op, char* init )
+{
+ double longOp = 0;
+ double longRes = 0;
+
+ longOp = *(opType->convertToCDouble(op + opOff, &longOp));
+ longRes = *(resType->convertToCDouble(init + resOff, &longRes));
+
+ if(longOp < longRes) {
+ resType->makeFromCDouble(init + resOff, &longOp);
+ }
+
+ return init;
+}
+
+char*
+OpMINCDouble::operator()( const char* op )
+{
+ return OpMINCDouble::operator()(op, accu);
+}
+
+OpSUMCULong::OpSUMCULong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ r_ULong myVal = 0;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ resType->makeFromCULong(accu, &myVal);
+}
+
+OpSUMCULong::OpSUMCULong( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpSUMCULong::operator()( const char* op, char* init )
+{
+ r_ULong longOp = 0;
+ r_ULong longRes = 0;
+
+ opType->convertToCULong(op + opOff, &longOp);
+ resType->convertToCULong(init + resOff, &longRes);
+
+ longRes += longOp;
+ resType->makeFromCULong( init + resOff, &longRes);
+
+ return init;
+}
+
+char*
+OpSUMCULong::operator()( const char* op )
+{
+ return OpSUMCULong::operator()(op, accu);
+}
+
+OpSUMCLong::OpSUMCLong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ r_Long myVal = 0;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ resType->makeFromCLong(accu, &myVal);
+}
+
+OpSUMCLong::OpSUMCLong( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpSUMCLong::operator()( const char* op, char* init )
+{
+ r_Long longOp = 0;
+ r_Long longRes = 0;
+
+ longOp = *(opType->convertToCLong(op + opOff, &longOp));
+ longRes = *(resType->convertToCLong(init + resOff, &longRes));
+
+ longRes = longOp + longRes;
+ resType->makeFromCLong( init + resOff, &longRes);
+
+ return init;
+}
+
+char*
+OpSUMCLong::operator()( const char* op )
+{
+ return OpSUMCLong::operator()(op, accu);
+}
+
+OpSUMCDouble::OpSUMCDouble( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff, unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ double myVal = 0.0;
+ // initialising with neutral value
+ accu = new char[resType->getSize()];
+ resType->makeFromCDouble(accu, &myVal);
+}
+
+OpSUMCDouble::OpSUMCDouble( const BaseType* newResType, char* newAccu,
+ const BaseType* newOpType, unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newAccu, newOpType, newResOff, newOpOff)
+{
+}
+
+char*
+OpSUMCDouble::operator()( const char* op, char* init )
+{
+ double longOp = 0;
+ double longRes = 0;
+
+ longOp = *(opType->convertToCDouble(op + opOff, &longOp));
+ longRes = *(resType->convertToCDouble(init + resOff, &longRes));
+
+ longRes = longOp + longRes;
+ resType->makeFromCDouble( init + resOff, &longRes);
+
+ return init;
+}
+
+char*
+OpSUMCDouble::operator()( const char* op )
+{
+ return OpSUMCDouble::operator()(op, accu);
+}
+
+OpCondenseStruct::OpCondenseStruct(
+ const BaseType* newResType,
+ const BaseType* newOpType,
+ Ops::OpType op,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ int i = 0;
+
+ myResType = (StructType*)newResType;
+ myOpType = (StructType*)newOpType;
+ numElems = myOpType->getNumElems();
+ elemOps = new CondenseOp*[numElems];
+ for(i = 0; i < numElems; i++) {
+ elemOps[i] = Ops::getCondenseOp(
+ op,
+ myResType->getElemType(i),
+ myOpType->getElemType(i),
+ newResOff + myResType->getOffset(i),
+ newOpOff + myOpType->getOffset(i)
+ );
+ }
+
+ accu = new char[resType->getSize()];
+ for(i = 0; i < numElems; i++) {
+ memcpy(accu + myResType->getOffset(i), elemOps[i]->getAccuVal(),
+ myResType->getElemType(i)->getSize());
+ }
+
+}
+
+//--------------------------------------------
+// OpCondenseStruct
+//--------------------------------------------
+
+OpCondenseStruct::OpCondenseStruct(
+ const BaseType* newResType,
+ char* newAccu,
+ const BaseType* newOpType,
+ Ops::OpType op,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : CondenseOp(newResType, newOpType, newResOff, newOpOff)
+{
+ int i = 0;
+
+ myResType = (StructType*)newResType;
+ myOpType = (StructType*)newOpType;
+ numElems = myOpType->getNumElems();
+ elemOps = new CondenseOp*[numElems];
+ for(i = 0; i < numElems; i++) {
+ elemOps[i] = Ops::getCondenseOp(
+ op,
+ myResType->getElemType(i),
+ myOpType->getElemType(i),
+ newResOff + myResType->getOffset(i),
+ newOpOff + myOpType->getOffset(i)
+ );
+ }
+
+ accu = new char[resType->getSize()];
+ memcpy(accu, newAccu, resType->getSize());
+}
+
+OpCondenseStruct::~OpCondenseStruct()
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ delete elemOps[i];
+ }
+ delete[] elemOps;
+}
+
+char*
+OpCondenseStruct::operator()( const char* op, char* init )
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ (*elemOps[i])(op, init);
+ }
+ return init;
+}
+
+char*
+OpCondenseStruct::operator()( const char* op )
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ (*elemOps[i])(op, accu);
+ }
+ return accu;
+}
+
+
+
+//--------------------------------------------
+// OpBinaryStruct
+//--------------------------------------------
+
+static Ops::OpType _operation;
+
+OpBinaryStruct::OpBinaryStruct( const BaseType* newStructType, Ops::OpType op,
+ unsigned int newResOff, unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newStructType, newStructType, newStructType, newResOff,
+ newOp1Off, newOp2Off)
+{
+ int i = 0;
+
+ _operation = op;
+
+ myStructType = (StructType*)newStructType;
+ numElems = myStructType->getNumElems();
+ elemOps = new BinaryOp*[numElems];
+ for(i = 0; i < numElems; i++) {
+ elemOps[i] = Ops::getBinaryOp( op, myStructType->getElemType(i),
+ myStructType->getElemType(i),
+ myStructType->getElemType(i),
+ newResOff + myStructType->getOffset(i),
+ newOp1Off + myStructType->getOffset(i),
+ newOp2Off + myStructType->getOffset(i) );
+ }
+}
+
+OpBinaryStruct::~OpBinaryStruct()
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ delete elemOps[i];
+ }
+ delete[] elemOps;
+}
+
+void
+OpBinaryStruct::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ int i;
+
+ if( _operation == Ops::OP_OVERLAY )
+ {
+ RMInit::logOut << "OpBinaryStruct operation" << endl;
+ for(i = 0; i < numElems; ++i)
+ if(*(op2 + op2Off)) {
+ for(int j = 0; j < numElems; ++j)
+ *(res + resOff) = *(op2 + op2Off);
+ return;
+ }
+ }
+
+
+ for(i = 0; i < numElems; i++) {
+ (*elemOps[i])(res, op1, op2);
+ }
+
+}
+
+//--------------------------------------------
+// OpBinaryStructConst
+//--------------------------------------------
+
+OpBinaryStructConst::OpBinaryStructConst(
+ const BaseType* res,
+ const BaseType* op1,
+ const BaseType* op2,
+ Ops::OpType op,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(res, op1, op2, newResOff,
+ newOp1Off, newOp2Off)
+{
+ int i = 0;
+
+ resStructType = (StructType*)resType;
+ opStructType = (StructType*)op1Type;
+ numElems = opStructType->getNumElems();
+ elemOps = new BinaryOp*[numElems];
+ for(i = 0; i < numElems; i++) {
+ elemOps[i] = Ops::getBinaryOp( op,
+ resStructType->getElemType(i),
+ opStructType->getElemType(i),
+ op2Type,
+ newResOff + resStructType->getOffset(i),
+ newOp1Off + opStructType->getOffset(i),
+ newOp2Off );
+ }
+}
+
+OpBinaryStructConst::~OpBinaryStructConst()
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ delete elemOps[i];
+ }
+ delete[] elemOps;
+}
+
+void
+OpBinaryStructConst::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ (*elemOps[i])(res, op1, op2);
+ }
+}
+
+//--------------------------------------------
+// OpBinaryConstStruct
+//--------------------------------------------
+
+OpBinaryConstStruct::OpBinaryConstStruct(
+ const BaseType* res,
+ const BaseType* op1,
+ const BaseType* op2,
+ Ops::OpType op,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(res, op1, op2, newResOff,
+ newOp1Off, newOp2Off)
+{
+ int i = 0;
+
+ resStructType = (StructType*)resType;
+ opStructType = (StructType*)op2Type;
+ numElems = opStructType->getNumElems();
+ elemOps = new BinaryOp*[numElems];
+ for(i = 0; i < numElems; i++) {
+ elemOps[i] = Ops::getBinaryOp( op,
+ resStructType->getElemType(i),
+ op1Type,
+ opStructType->getElemType(i),
+ newResOff + resStructType->getOffset(i),
+ newOp1Off,
+ newOp2Off + opStructType->getOffset(i) );
+ }
+}
+
+OpBinaryConstStruct::~OpBinaryConstStruct()
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ delete elemOps[i];
+ }
+ delete[] elemOps;
+}
+
+void
+OpBinaryConstStruct::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ (*elemOps[i])(res, op1, op2);
+ }
+}
+
+//--------------------------------------------
+// OpEQUALStruct
+//--------------------------------------------
+
+OpEQUALStruct::OpEQUALStruct( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+ int i = 0;
+
+ numElems = ((StructType*)op1Type)->getNumElems();
+ elemOps = new BinaryOp*[numElems];
+ for(i = 0; i < numElems; i++) {
+ elemOps[i] =
+ Ops::getBinaryOp( Ops::OP_EQUAL, resType,
+ ((StructType*)op1Type)->getElemType(i),
+ ((StructType*)op2Type)->getElemType(i),
+ newResOff,
+ newOp1Off + ((StructType*)op1Type)->getOffset(i),
+ newOp2Off + ((StructType*)op2Type)->getOffset(i) );
+ }
+}
+
+OpEQUALStruct::~OpEQUALStruct()
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ delete elemOps[i];
+ }
+ delete[] elemOps;
+}
+
+void
+OpEQUALStruct::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ int i;
+ char dummy = 1;
+
+ for(i = 0; i < numElems; i++) {
+ (*elemOps[i])(res, op1, op2);
+ dummy = *res && dummy;
+ }
+ *res = dummy;
+}
+
+//--------------------------------------------
+// OpNOTEQUALStruct
+//--------------------------------------------
+
+OpNOTEQUALStruct::OpNOTEQUALStruct( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+ int i = 0;
+
+ numElems = ((StructType*)op1Type)->getNumElems();
+ elemOps = new BinaryOp*[numElems];
+ for(i = 0; i < numElems; i++) {
+ elemOps[i] =
+ Ops::getBinaryOp( Ops::OP_NOTEQUAL, resType,
+ ((StructType*)op1Type)->getElemType(i),
+ ((StructType*)op2Type)->getElemType(i),
+ newResOff,
+ newOp1Off + ((StructType*)op1Type)->getOffset(i),
+ newOp2Off + ((StructType*)op2Type)->getOffset(i) );
+ }
+}
+
+OpNOTEQUALStruct::~OpNOTEQUALStruct()
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ delete elemOps[i];
+ }
+ delete[] elemOps;
+}
+
+void
+OpNOTEQUALStruct::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ int i;
+ char dummy = 0;
+
+ for(i = 0; i < numElems; i++) {
+ (*elemOps[i])(res, op1, op2);
+ dummy = *res || dummy;
+ }
+ *res = dummy;
+}
+
+//--------------------------------------------
+// OpUnaryStruct
+//--------------------------------------------
+
+OpUnaryStruct::OpUnaryStruct(
+ const BaseType* newResType,
+ const BaseType* newOpType,
+ Ops::OpType op,
+ unsigned int newResOff,
+ unsigned int newOpOff)
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+ int i = 0;
+
+ myResType = (StructType*)newResType;
+ myOpType = (StructType*)newOpType;
+ numElems = myOpType->getNumElems();
+ elemOps = new UnaryOp*[numElems];
+ for(i = 0; i < numElems; i++) {
+ elemOps[i] = Ops::getUnaryOp(
+ op,
+ myResType->getElemType(i),
+ myOpType->getElemType(i),
+ newResOff + myResType->getOffset(i),
+ newOpOff + myOpType->getOffset(i)
+ );
+ }
+}
+
+OpUnaryStruct::~OpUnaryStruct()
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ delete elemOps[i];
+ }
+ delete[] elemOps;
+}
+
+void
+OpUnaryStruct::operator()( char* result, const char* op )
+{
+ int i;
+
+ for(i = 0; i < numElems; i++) {
+ try {
+ (*elemOps[i])(result, op);
+ }
+ catch(...) {
+ // cleanup
+ for(i = 0; i < numElems; i++) {
+ delete elemOps[i];
+ }
+ delete[] elemOps;
+ throw;
+ }
+ }
+}
+
+//--------------------------------------------
+// OpPLUSChar
+//--------------------------------------------
+
+OpPLUSChar::OpPLUSChar( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpPLUSChar::operator()( char* res, const char* op1, const char* op2 )
+{
+ *(unsigned char*)(res + resOff) =
+ *(unsigned char*)(op1 + op1Off) + *(unsigned char*)(op2 + op2Off);
+}
+
+void
+OpPLUSChar::getCondenseInit(char* init)
+{
+ *init = 0;
+}
+
+//--------------------------------------------
+// OpMINUSChar
+//--------------------------------------------
+
+OpMINUSChar::OpMINUSChar( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpMINUSChar::operator()( char* res, const char* op1, const char* op2 )
+{
+ *(unsigned char*)(res + resOff) =
+ *(unsigned char*)(op1 + op1Off) - *(unsigned char*)(op2 + op2Off);
+}
+
+//--------------------------------------------
+// OpDIVChar
+//--------------------------------------------
+
+OpDIVChar::OpDIVChar( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpDIVChar::operator()( char* res, const char* op1, const char* op2 )
+{
+ if(*(unsigned char*)(op2 + op2Off) == 0)
+ // catch division by zero, perhaps should throw exception
+ *(unsigned char*)(res + resOff) = 0;
+ else {
+ *(unsigned char*)(res + resOff) = *(unsigned char*)(op1 + op1Off) /
+ *(unsigned char*)(op2 + op2Off);
+ }
+}
+
+//--------------------------------------------
+// OpMULTChar
+//--------------------------------------------
+
+OpMULTChar::OpMULTChar( const BaseType* newResType, const BaseType* newOp1Type,
+ const BaseType* newOp2Type, unsigned int newResOff,
+ unsigned int newOp1Off, unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpMULTChar::operator()( char* res, const char* op1, const char* op2 )
+{
+ *(unsigned char*)(res + resOff) =
+ *(unsigned char*)(op1 + op1Off) * *(unsigned char*)(op2 + op2Off);
+}
+
+void
+OpMULTChar::getCondenseInit(char* init)
+{
+ *init = 1;
+}
+
+//--------------------------------------------
+// OpEQUALChar
+//--------------------------------------------
+
+OpEQUALChar::OpEQUALChar( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpEQUALChar::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ *(unsigned char*)(res + resOff) = *(unsigned char*)(op1 + op1Off) ==
+ *(unsigned char*)(op2 + op2Off);
+}
+
+//--------------------------------------------
+// OpLESSChar
+//--------------------------------------------
+
+OpLESSChar::OpLESSChar( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpLESSChar::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ *(unsigned char*)(res + resOff) = *(unsigned char*)(op1 + op1Off) <
+ *(unsigned char*)(op2 + op2Off);
+}
+
+//--------------------------------------------
+// OpLESSEQUALChar
+//--------------------------------------------
+
+OpLESSEQUALChar::OpLESSEQUALChar( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpLESSEQUALChar::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ *(unsigned char*)(res + resOff) = *(unsigned char*)(op1 + op1Off) <=
+ *(unsigned char*)(op2 + op2Off);
+}
+
+//--------------------------------------------
+// OpNOTEQUALChar
+//--------------------------------------------
+
+OpNOTEQUALChar::OpNOTEQUALChar( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpNOTEQUALChar::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ *(unsigned char*)(res + resOff) = *(unsigned char*)(op1 + op1Off) !=
+ *(unsigned char*)(op2 + op2Off);
+}
+
+
+//--------------------------------------------
+// OpGREATERChar
+//--------------------------------------------
+
+OpGREATERChar::OpGREATERChar( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpGREATERChar::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ *(unsigned char*)(res + resOff) = *(unsigned char*)(op1 + op1Off) >
+ *(unsigned char*)(op2 + op2Off);
+}
+
+
+
+//--------------------------------------------
+// OpGREATEREQUALChar
+//--------------------------------------------
+
+OpGREATEREQUALChar::OpGREATEREQUALChar( const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off )
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff,
+ newOp1Off, newOp2Off)
+{
+}
+
+void
+OpGREATEREQUALChar::operator()( char* res, const char* op1,
+ const char* op2 )
+{
+ *(unsigned char*)(res + resOff) = *(unsigned char*)(op1 + op1Off) >=
+ *(unsigned char*)(op2 + op2Off);
+}
+
+//--------------------------------------------
+// OpIDENTITYChar
+//--------------------------------------------
+
+OpIDENTITYChar::OpIDENTITYChar( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpIDENTITYChar::operator()( char* res, const char* op )
+{
+ *(unsigned char*)(res + resOff) = *(unsigned char*)(op + opOff);
+}
+
+//--------------------------------------------
+//
+//--------------------------------------------
+
+OpIDENTITYShort::OpIDENTITYShort( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpIDENTITYShort::operator()( char* res, const char* op )
+{
+ *(unsigned short*)(res + resOff) = *(unsigned short*)(op + opOff);
+}
+
+//--------------------------------------------
+// OpIDENTITYLong
+//--------------------------------------------
+
+OpIDENTITYLong::OpIDENTITYLong( const BaseType* newResType, const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+}
+
+void
+OpIDENTITYLong::operator()( char* res, const char* op )
+{
+ *(r_ULong*)(res + resOff) = *(r_ULong*)(op + opOff);
+}
+
+//--------------------------------------------
+// MarrayOp
+//--------------------------------------------
+
+MarrayOp::MarrayOp( const BaseType* newResType, unsigned int newResOff )
+ : resType(newResType), resOff(newResOff)
+{
+}
+
+void
+MarrayOp::operator()( char* result, const r_Point& p )
+{
+ r_ULong sum = 0;
+
+ for(int i = 0; i < p.dimension(); i++)
+ sum += p[i];
+
+ resType->makeFromCULong(result, &sum);
+}
+
+//--------------------------------------------
+// GenCondenseOp
+//--------------------------------------------
+
+GenCondenseOp::GenCondenseOp( const BaseType* newResType, unsigned int newResOff,
+ BinaryOp* newAccuOp, char* newInitVal )
+ : resType(newResType), resOff(newResOff), accuOp(newAccuOp), myInitVal(0)
+{
+ if(newInitVal == 0) {
+ initVal = new char[resType->getSize()];
+ myInitVal = 1;
+ accuOp->getCondenseInit(initVal);
+ }
+ else
+ initVal = newInitVal;
+}
+
+GenCondenseOp::~GenCondenseOp()
+{
+ if(myInitVal)
+ delete [] initVal;
+}
+
+
+void
+GenCondenseOp::operator()( const r_Point& p )
+{
+ r_ULong sum = 0;
+ char buf[8];
+
+ for(int i = 0; i < p.dimension(); i++)
+ sum += p[i];
+
+ resType->makeFromCULong(buf, &sum);
+
+ (*accuOp)(initVal, initVal, buf);
+}
+
+BinaryOp*
+GenCondenseOp::getAccuOp()
+{
+ return accuOp;
+}
+
+const BaseType*
+GenCondenseOp::getResultType()
+{
+ return resType;
+}
+
+unsigned int
+GenCondenseOp::getResultOff()
+{
+ return resOff;
+}
+
+char*
+GenCondenseOp::getAccuVal()
+{
+ return initVal;
+}
+
+
+//--------------------------------------------
+// Complex
+//--------------------------------------------
+
+// *** PLUS ***
+
+OpPLUSComplex::OpPLUSComplex(
+ const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off,
+ ScalarFlag flag)
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff, newOp1Off, newOp2Off), scalarFlag(flag)
+{
+ op1ReOff = scalarFlag == OpPLUSComplex::FIRST ? 0: ((GenericComplexType *)newOp1Type)->getReOffset();
+ op1ImOff = scalarFlag == OpPLUSComplex::FIRST ? 0: ((GenericComplexType *)newOp1Type)->getImOffset();
+ op2ReOff = scalarFlag == OpPLUSComplex::SECOND ? 0: ((GenericComplexType *)newOp2Type)->getReOffset();
+ op2ImOff = scalarFlag == OpPLUSComplex::SECOND ? 0: ((GenericComplexType *)newOp2Type)->getImOffset();
+
+ resReOff = ((GenericComplexType *)newResType)->getReOffset();
+ resImOff = ((GenericComplexType *)newResType)->getImOffset();
+}
+
+void OpPLUSComplex::operator()(char* res, const char* op1, const char* op2) {
+ double op1Re = 0;
+ double op2Re = 0;
+ double op1Im = 0;
+ double op2Im = 0;
+ double resRe, resIm;
+
+ if(scalarFlag == FIRST) {
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) +
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im));
+ }
+ else if(scalarFlag == SECOND) {
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) +
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im));
+ }
+ else {
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) +
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im)) +
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im));
+ }
+
+ resType->makeFromCDouble(res + resOff + resReOff, &resRe);
+ resType->makeFromCDouble(res + resOff + resImOff, &resIm);
+}
+
+void OpPLUSComplex::getCondenseInit(char* init) {
+ double dummyRe = 0.0;
+ double dummyIm = 0.0;
+ resType->makeFromCDouble(init + resReOff, &dummyRe);
+ resType->makeFromCDouble(init + resImOff, &dummyIm);
+}
+
+// *** MINUS ***
+
+
+OpMINUSComplex::OpMINUSComplex(
+ const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off,
+ ScalarFlag flag)
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff, newOp1Off, newOp2Off), scalarFlag(flag)
+{
+ op1ReOff = scalarFlag == OpPLUSComplex::FIRST ? 0: ((GenericComplexType *)newOp1Type)->getReOffset();
+ op1ImOff = scalarFlag == OpPLUSComplex::FIRST ? 0: ((GenericComplexType *)newOp1Type)->getImOffset();
+ op2ReOff = scalarFlag == OpPLUSComplex::SECOND ? 0: ((GenericComplexType *)newOp2Type)->getReOffset();
+ op2ImOff = scalarFlag == OpPLUSComplex::SECOND ? 0: ((GenericComplexType *)newOp2Type)->getImOffset();
+
+ resReOff = ((GenericComplexType *)newResType)->getReOffset();
+ resImOff = ((GenericComplexType *)newResType)->getImOffset();
+}
+
+void OpMINUSComplex::operator()(char* res, const char* op1, const char* op2) {
+ double op1Re = 0;
+ double op2Re = 0;
+ double op1Im = 0;
+ double op2Im = 0;
+ double resRe, resIm;
+
+ if(scalarFlag == FIRST) {
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) -
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im));
+ }
+ else if(scalarFlag == SECOND) {
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) -
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im));
+ }
+ else {
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) -
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im)) -
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im));
+ }
+
+ resType->makeFromCDouble(res + resOff + resReOff, &resRe);
+ resType->makeFromCDouble(res + resOff + resImOff, &resIm);
+}
+
+// *** DIV ***
+
+OpDIVComplex::OpDIVComplex(
+ const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off,
+ ScalarFlag flag)
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff, newOp1Off, newOp2Off), scalarFlag(flag)
+{
+ op1ReOff = scalarFlag == OpPLUSComplex::FIRST ? 0: ((GenericComplexType *)newOp1Type)->getReOffset();
+ op1ImOff = scalarFlag == OpPLUSComplex::FIRST ? 0: ((GenericComplexType *)newOp1Type)->getImOffset();
+ op2ReOff = scalarFlag == OpPLUSComplex::SECOND ? 0: ((GenericComplexType *)newOp2Type)->getReOffset();
+ op2ImOff = scalarFlag == OpPLUSComplex::SECOND ? 0: ((GenericComplexType *)newOp2Type)->getImOffset();
+
+ resReOff = ((GenericComplexType *)newResType)->getReOffset();
+ resImOff = ((GenericComplexType *)newResType)->getImOffset();
+}
+
+void OpDIVComplex::operator()(char* res, const char* op1, const char* op2) {
+ double op1Re = 0;
+ double op2Re = 0;
+ double op1Im = 0;
+ double op2Im = 0;
+ double resRe, resIm;
+
+ if(scalarFlag == FIRST) {
+ double a = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re));
+ double x = *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+ double y = *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im));
+
+ resRe = a * x / (x * x + y * y);
+ resIm = - a * y / (x * x + y * y);
+ }
+ else if(scalarFlag == SECOND) {
+
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) /
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im)) /
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im));
+ }
+ else { // NONE
+ double x1 = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re));
+ double y1 = *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im));
+ double x2 = *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+ double y2 = *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im));
+
+ resRe = (x1 * x2 + y1 * y2) / (x2 * x2 + y2 * y2);
+ resIm = (y1 * x2 - x1 * y2) / (x2 * x2 + y2 * y2);
+ }
+
+ resType->makeFromCDouble(res + resOff + resReOff, &resRe);
+ resType->makeFromCDouble(res + resOff + resImOff, &resIm);
+}
+
+// *** MULT ***
+
+OpMULTComplex::OpMULTComplex(
+ const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off,
+ ScalarFlag flag)
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff, newOp1Off, newOp2Off), scalarFlag(flag)
+{
+ op1ReOff = scalarFlag == OpPLUSComplex::FIRST ? 0: ((GenericComplexType *)newOp1Type)->getReOffset();
+ op1ImOff = scalarFlag == OpPLUSComplex::FIRST ? 0: ((GenericComplexType *)newOp1Type)->getImOffset();
+ op2ReOff = scalarFlag == OpPLUSComplex::SECOND ? 0: ((GenericComplexType *)newOp2Type)->getReOffset();
+ op2ImOff = scalarFlag == OpPLUSComplex::SECOND ? 0: ((GenericComplexType *)newOp2Type)->getImOffset();
+
+ resReOff = ((GenericComplexType *)newResType)->getReOffset();
+ resImOff = ((GenericComplexType *)newResType)->getImOffset();
+}
+
+void OpMULTComplex::operator()(char* res, const char* op1, const char* op2) {
+ double op1Re = 0;
+ double op2Re = 0;
+ double op1Im = 0;
+ double op2Im = 0;
+ double resRe, resIm;
+
+
+ if(scalarFlag == FIRST) {
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) *
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) *
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im));
+ }
+ else if(scalarFlag == SECOND) {
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) *
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+
+ resIm = *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im)) *
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re));
+ }
+ else {
+ // Re = x1 * x2 - y1 * y2
+
+ resRe = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) * // x1
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re)) - // x2
+ *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im)) * // y1
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im)); // y2
+
+ // Im = x1 * y2 + x2 * y1
+
+ resIm = *(op1Type->convertToCDouble(op1 + op1Off + op1ReOff, &op1Re)) * // x1
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ImOff, &op2Im)) + // y2
+ *(op2Type->convertToCDouble(op2 + op2Off + op2ReOff, &op2Re)) * // x2
+ *(op1Type->convertToCDouble(op1 + op1Off + op1ImOff, &op1Im)); // y1
+ }
+
+ resType->makeFromCDouble(res + resOff + resReOff, &resRe);
+ resType->makeFromCDouble(res + resOff + resImOff, &resIm);
+}
+
+void OpMULTComplex::getCondenseInit(char* init) {
+ double dummyRe = 0.0;
+ double dummyIm = 0.0;
+ resType->makeFromCDouble(init + resReOff, &dummyRe);
+ resType->makeFromCDouble(init + resImOff, &dummyIm);
+}
+
+// *** IDENTITY ***
+
+OpIDENTITYComplex::OpIDENTITYComplex(
+ const BaseType* newResType,
+ const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff )
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{}
+
+void OpIDENTITYComplex::operator()(char* res, const char* op) {
+ memcpy((void *)(res + resOff), (void *)(op + opOff), resType->getSize());
+}
+
+// *** REAL PART ***
+
+OpRealPart::OpRealPart(
+ const BaseType* newResType,
+ const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff)
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+ opReOff = ((GenericComplexType *)newOpType)->getReOffset();
+}
+
+
+void OpRealPart::operator()(char* res, const char* op) {
+ double result;
+
+ opType->convertToCDouble(op + opOff + opReOff, &result);
+ resType->makeFromCDouble(res + resOff, &result);
+}
+
+// *** IMAGINAR PART ***
+
+OpImaginarPart::OpImaginarPart(
+ const BaseType* newResType,
+ const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff)
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff)
+{
+ opImOff = ((GenericComplexType *)newOpType)->getImOffset();
+}
+
+
+void OpImaginarPart::operator()(char* res, const char* op) {
+ double result;
+
+ opType->convertToCDouble(op + opOff + opImOff, &result);
+ resType->makeFromCDouble(res + resOff, &result);
+}
+
+
+//--------------------------------------------
+// OpCAST
+//--------------------------------------------
+
+OpCAST::OpCAST(
+ const BaseType* newResType,
+ const BaseType* newOpType,
+ unsigned int newResOff,
+ unsigned int newOpOff)
+ : UnaryOp(newResType, newOpType, newResOff, newOpOff) {}
+
+void OpCAST::operator()(char* res, const char* op) {
+
+ if(resType->getType() == FLOAT || resType->getType() == DOUBLE) {
+ // floating point types
+ double dblOp;
+ double dblRes = *(opType->convertToCDouble(op + opOff, &dblOp));
+ resType->makeFromCDouble(res + resOff, &dblRes);
+ }
+ else {
+ // all integral types
+ r_Long lngOp;
+ r_Long lngRes = *(opType->convertToCLong(op + opOff, &lngOp));
+ resType->makeFromCLong(res + resOff, &lngRes);
+ }
+}
+
+
+//--------------------------------------------
+// OpOVERLAY
+//--------------------------------------------
+
+OpOVERLAY::OpOVERLAY( const BaseType* newResType, const BaseType* newOp1Type, const BaseType* newOp2Type, size_t typeSize, const char* transparentPattern, unsigned int newResOff, unsigned int newOp1Off, unsigned int newOp2Off)
+ : BinaryOp(newResType, newOp1Type, newOp2Type, newResOff, newOp1Off, newOp2Off), length(typeSize), pattern(transparentPattern)
+{
+ if ((pattern == nullPattern) && (length > 16))
+ {
+ RMInit::logOut << "OpOVERLAY overlay with types larger than 16 bytes not supported yet" << endl;
+ throw r_Error(OVERLAYPATTERNTOOSMALL);
+ }
+}
+
+void OpOVERLAY::operator()( char *res, const char *op1, const char *op2 )
+{
+ if (memcmp(pattern, op1 + op1Off, length) == 0)
+ {//match
+ memcpy(res + resOff, op2 + op2Off, length);
+ }
+ else {//no match
+ memcpy(res + resOff, op1 + op1Off, length);
+ }
+}
+
+const char*
+OpOVERLAY::nullPattern = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+
+//--------------------------------------------
+// OpBIT
+//--------------------------------------------
+
+OpBIT::OpBIT(
+ const BaseType* newResType,
+ const BaseType* newOp1Type,
+ const BaseType* newOp2Type,
+ unsigned int newResOff,
+ unsigned int newOp1Off,
+ unsigned int newOp2Off)
+
+ : BinaryOp(newResType,
+ newOp1Type, newOp2Type,
+ newResOff, newOp1Off,
+ newOp2Off)
+ {}
+
+
+void OpBIT::operator() (char *res, const char *op1, const char *op2) {
+ r_ULong lngOp1, lngOp2, lngRes;
+
+ op1Type->convertToCULong(op1 + op1Off, &lngOp1);
+ op2Type->convertToCULong(op2 + op2Off, &lngOp2);
+ lngRes = lngOp1 >> lngOp2 & 0x1L;
+ resType->makeFromCULong(res + resOff, &lngRes);
+}
+
+
+
+
+#include "autogen_ops.cc"