From 8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 Mon Sep 17 00:00:00 2001 From: Constantin Jucovschi Date: Fri, 24 Apr 2009 07:20:22 -0400 Subject: Initial commit --- catalogmgr/Makefile.am | 43 + catalogmgr/algebraops.cc | 172 ++ catalogmgr/algebraops.hh | 130 ++ catalogmgr/autogen_ops.cc | 316 ++++ catalogmgr/autogen_ops.hh | 284 ++++ catalogmgr/ops.cc | 3803 +++++++++++++++++++++++++++++++++++++++++++++ catalogmgr/ops.hh | 2042 ++++++++++++++++++++++++ catalogmgr/test/Makefile | 58 + catalogmgr/typefactory.cc | 626 ++++++++ catalogmgr/typefactory.hh | 262 ++++ 10 files changed, 7736 insertions(+) create mode 100644 catalogmgr/Makefile.am create mode 100644 catalogmgr/algebraops.cc create mode 100644 catalogmgr/algebraops.hh create mode 100644 catalogmgr/autogen_ops.cc create mode 100644 catalogmgr/autogen_ops.hh create mode 100644 catalogmgr/ops.cc create mode 100644 catalogmgr/ops.hh create mode 100644 catalogmgr/test/Makefile create mode 100644 catalogmgr/typefactory.cc create mode 100644 catalogmgr/typefactory.hh (limited to 'catalogmgr') diff --git a/catalogmgr/Makefile.am b/catalogmgr/Makefile.am new file mode 100644 index 0000000..b7b8c08 --- /dev/null +++ b/catalogmgr/Makefile.am @@ -0,0 +1,43 @@ +# -*-Makefile-*- (for Emacs) +# 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 . +# +# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +# rasdaman GmbH. +# +# For more information please see +# or contact Peter Baumann via . +# +# MAKEFILE FOR: +# catalogmgr +# +# COMMENTS: +# +################################################################## + + +RMANBASE=@abs_top_srcdir@ +BASEDBCXXFLAGS=@BASEDBCXXFLAGS@ +BASEDBLDFLAGS=@BASEDBLDFLAGS@ + +AM_CXXFLAGS= $(BASEDBCXXFLAGS) +AM_LDFLAGS= $(BASEDBLDFLAGS) + +# object files to put in library +noinst_LIBRARIES=libcatalogmgr.a +libcatalogmgr_a_SOURCES=ops.cc typefactory.cc algebraops.cc ops.hh \ + typefactory.hh algebraops.hh autogen_ops.hh +EXTRA_libcatalogmgr_a_SOURCES = autogen_ops.cc + diff --git a/catalogmgr/algebraops.cc b/catalogmgr/algebraops.cc new file mode 100644 index 0000000..559a797 --- /dev/null +++ b/catalogmgr/algebraops.cc @@ -0,0 +1,172 @@ +/* +* 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 . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +/************************************************************* + * + * + * + * + * COMMENTS: + * + ************************************************************/ + +static const char rcsid[] = "@(#)qlparser, QLMarrayOp, QLCondenseOp: $Header: /home/rasdev/CVS-repository/rasdaman/catalogmgr/algebraops.cc,v 1.5 2003/12/20 23:41:27 rasdev Exp $"; + +#include "raslib/rmdebug.hh" + +#include "algebraops.hh" + +#include "qlparser/qtoperation.hh" +#include "qlparser/qtdata.hh" +#include "qlparser/qtpointdata.hh" +#include "qlparser/qtscalardata.hh" +#include "qlparser/qtatomicdata.hh" + +#include "relcatalogif/basetype.hh" + +QLMarrayOp::QLMarrayOp( QtOperation* newCellExpression, + std::vector* newDataList, + std::string &newIteratorName, + BaseType* newResType, + unsigned int newResOff ) : + MarrayOp( newResType, newResOff ), + cellExpression( newCellExpression ), + dataList( newDataList ), + iteratorName( newIteratorName ) +{ +} + + + +QLMarrayOp::~QLMarrayOp() +{ +} + + + +void +QLMarrayOp::operator() ( char *result, const r_Point &p ) +{ + // update point data of input list + if ( dataList ) + ((QtPointData *)dataList->back())->setPointData( p ); + + if ( cellExpression ) { + QtData* resultData = cellExpression->evaluate( dataList ); + + if( resultData ) { + if( resultData->isScalarData() ) { + QtScalarData* scalarResultData = (QtScalarData*)resultData; + memcpy( (void*)result, + (void*)scalarResultData->getValueBuffer(), + scalarResultData->getValueType()->getSize() ); + } + else + RMInit::logOut << "Internal Error: QLMarrayOp::operator() - cell type invalid." << endl; + resultData->deleteRef(); + } + } +} + + + + +QLCondenseOp::QLCondenseOp( QtOperation* newCellExpression, + QtOperation* newCondExpression, + std::vector* newDataList, + std::string &newIteratorName, + BaseType* newResType, + unsigned int newResOff, + BinaryOp* newAccuOp, + char* newInitVal ) + + : GenCondenseOp( newResType, newResOff, newAccuOp, newInitVal ), + cellExpression( newCellExpression ), + condExpression( newCondExpression ), + dataList( newDataList ), + iteratorName( newIteratorName ) +{ + // + // add point with its iterator name to the data list + // + + // create QtPointData object + QtPointData* pointData = new QtPointData( r_Point() ); + + // set its iterator name + pointData->setIteratorName( iteratorName ); + + // add it to the list + dataList->push_back( pointData ); +} + + + +QLCondenseOp::~QLCondenseOp() +{ + // remove point data object from inputList again + dataList->back()->deleteRef(); + dataList->pop_back(); +} + + + +void +QLCondenseOp::operator() ( const r_Point& p ) +{ + unsigned int currentCellValid = 1; + + // update point data of input list + if ( dataList ) + ((QtPointData*)dataList->back())->setPointData( p ); + + if ( condExpression ) { + QtData* condData = condExpression->evaluate( dataList ); +#ifdef QT_RUNTIME_TYPE_CHECK + if( condData->getDataType() != QT_BOOL ) { + RMInit::logOut << "Internal error in QLCondenseOp::operator() - " + << "runtime type checking failed (BOOL)." << endl; + } + else +#endif + currentCellValid = ((QtAtomicData*)condData)->getUnsignedValue(); + condData->deleteRef(); + } + + if ( currentCellValid ) { + QtData* resultData = cellExpression->evaluate( dataList ); + if ( resultData ) { +#ifdef QT_RUNTIME_TYPE_CHECK + if ( !(resultData->isScalarData()) ) { + RMInit::logOut << "Internal Error: QLCondenseOp::operator() - cell type invalid." << endl; + } + else +#endif + { + QtScalarData* scalarResultData = (QtScalarData*)resultData; + (*accuOp)( initVal, initVal, scalarResultData->getValueBuffer() ); + } + + resultData->deleteRef(); + } + } +} diff --git a/catalogmgr/algebraops.hh b/catalogmgr/algebraops.hh new file mode 100644 index 0000000..d026db1 --- /dev/null +++ b/catalogmgr/algebraops.hh @@ -0,0 +1,130 @@ +/* +* 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 . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +/************************************************************* + * + * + * + * + * COMMENTS: + * + ************************************************************/ + +#ifndef _ALGEBRAOPS_HH_ +#define _ALGEBRAOPS_HH__ + +#include "ops.hh" + +#include +#include + +// forward declarations +class QtOperation; +class QtData; + +//@ManMemo: Module: {\bf catalogif} + +/*@Doc: + + Operation object for marray contstructor of the query language. + +*/ + +class QLMarrayOp: public MarrayOp +{ + public: + /// constructor + QLMarrayOp( QtOperation* newCellExpression, std::vector* newDataList, + std::string &newIteratorName, + BaseType* newResType, unsigned int newResOff = 0 ); + /** + Constructor gets cell expression pointer, data vector for bounded variables, + cell type, and type offset + */ + + /// virtual destructor + virtual ~QLMarrayOp(); + + /// operator that carries out the cell expression on point {\tt p}. + virtual void operator() ( char* result, const r_Point& p ); + + private: + /// pointer to the cell expression + QtOperation* cellExpression; + + /// pointer to data vector + std::vector* dataList; + + /// name of the iterator + std::string iteratorName; +}; + + + + +//@ManMemo: Module: {\bf catalogif} + +/*@Doc: + + Operation object for condenser operation of the query language. + +*/ + +class QLCondenseOp: public GenCondenseOp +{ + public: + /// constructor + QLCondenseOp( QtOperation* newCellExpression, + QtOperation* newCondExpression, + std::vector* newDataList, + std::string &newIteratorName, + BaseType* newResType, + unsigned int newResOff, + BinaryOp* newAccuOp, + char* newInitVal = 0 ); + /** + Constructor gets cell expression pointer, cell condition expression pointer, + data vector for bounded variables, cell type, and type offset + */ + + /// virtual destructor + virtual ~QLCondenseOp(); + + /// operator that carries out the cell expression on point {\tt p}. + virtual void operator() ( const r_Point& p ); + + private: + /// pointer to the cell expression + QtOperation* cellExpression; + + /// pointer to the condition expression + QtOperation* condExpression; + + /// pointer to data vector + std::vector* dataList; + + /// name of the iterator + std::string iteratorName; +}; + +#endif + diff --git a/catalogmgr/autogen_ops.cc b/catalogmgr/autogen_ops.cc new file mode 100644 index 0000000..6e17cc8 --- /dev/null +++ b/catalogmgr/autogen_ops.cc @@ -0,0 +1,316 @@ +/* +* 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 . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +/************************************************************* + * + * + * + * + * COMMENTS: Automaticaly generated + * + ************************************************************/ + + +#include +#include + + +OpABSCDouble::OpABSCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpABSCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = fabs(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpSQRTCDouble::OpSQRTCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpSQRTCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = sqrt(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpEXPCDouble::OpEXPCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpEXPCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = exp(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpLOGCDouble::OpLOGCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpLOGCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = log10(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpLNCDouble::OpLNCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpLNCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = log(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpSINCDouble::OpSINCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpSINCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = sin(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpCOSCDouble::OpCOSCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpCOSCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = cos(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpTANCDouble::OpTANCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpTANCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = tan(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpSINHCDouble::OpSINHCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpSINHCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = sin(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpCOSHCDouble::OpCOSHCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpCOSHCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = cos(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpTANHCDouble::OpTANHCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpTANHCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = tan(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpARCSINCDouble::OpARCSINCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpARCSINCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = asin(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpARCCOSCDouble::OpARCCOSCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpARCCOSCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = acos(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + +OpARCTANCDouble::OpARCTANCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff, + unsigned int newOpOff) + : UnaryOp(newResType, newOpType, newResOff, newOpOff) {} + + +void OpARCTANCDouble::operator()(char* res, const char* op) { + double convOp; + double convRes; + errno = 0; + convRes = atan(*(opType->convertToCDouble(op + opOff, &convOp))); + if(errno) { + if(errno == EDOM) throw 510; + if(errno == ERANGE) throw 511; + } + resType->makeFromCDouble(res + resOff, &convRes); +} + diff --git a/catalogmgr/autogen_ops.hh b/catalogmgr/autogen_ops.hh new file mode 100644 index 0000000..28969be --- /dev/null +++ b/catalogmgr/autogen_ops.hh @@ -0,0 +1,284 @@ +/* +* 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 . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +/************************************************************* + * + * + * + * + * COMMENTS: Automaticaly generated + * + ************************************************************/ + + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpABSCDouble : public UnaryOp { +public: + OpABSCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpSQRTCDouble : public UnaryOp { +public: + OpSQRTCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpEXPCDouble : public UnaryOp { +public: + OpEXPCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpLOGCDouble : public UnaryOp { +public: + OpLOGCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpLNCDouble : public UnaryOp { +public: + OpLNCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpSINCDouble : public UnaryOp { +public: + OpSINCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpCOSCDouble : public UnaryOp { +public: + OpCOSCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpTANCDouble : public UnaryOp { +public: + OpTANCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpSINHCDouble : public UnaryOp { +public: + OpSINHCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpCOSHCDouble : public UnaryOp { +public: + OpCOSHCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpTANHCDouble : public UnaryOp { +public: + OpTANHCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpARCSINCDouble : public UnaryOp { +public: + OpARCSINCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpARCCOSCDouble : public UnaryOp { +public: + OpARCCOSCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + +//@ManMemo: Module: {\bf catalogmgr} + +/*@Doc: + +*/ + +// class declaration +class OpARCTANCDouble : public UnaryOp { +public: + OpARCTANCDouble( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); +}; + 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 . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +*/ +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 +#include +#include // memcpy() +#include // 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" diff --git a/catalogmgr/ops.hh b/catalogmgr/ops.hh new file mode 100644 index 0000000..61ffc40 --- /dev/null +++ b/catalogmgr/ops.hh @@ -0,0 +1,2042 @@ +/* +* 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 . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +/************************************************************* + * + * + * PURPOSE: + * Ops contains an enum for identifying all possible + * operations. + * + * + * COMMENTS: + * + ************************************************************/ + +#ifndef _OPS_HH_ +#define _OPS_HH_ + +#include + +class CondenseOp; +class UnaryOp; +class BinaryOp; +class BaseType; +class StructType; +class Tile; +class r_Point; + +//@Man: TypeEnum +//@Type: typedef +//@Memo: Module: {\bf catalogif}. + +enum TypeEnum +{ + ULONG, USHORT, CHAR, BOOLTYPE, LONG, SHORT, OCTET, DOUBLE, FLOAT, + COMPLEXTYPE1, // COMPLEX already defined as token !!! + COMPLEXTYPE2, + STRUCT, + CLASSTYPE, SETTYPE, MDDTYPE +}; + +/*@Doc: This is an enum used for handling types instead of using the + string representation of the name. For some strange reason + I did not manage to define it in Ops scope. I had to use BOOLTYPE + instead of BOOL because of name conflicts. + + Attention: DO NOT change the sequence because some code relies on it. +This is the ops code and the persistence code: from the typenum the oids are generated. changing the order of the enums makes old databases incompatible. there is already a migration tool which shows how to adapt the database schema. + */ + +//@ManMemo: Module: {\bf catalogif}. + +/*@Doc: + The class Ops is contains an enumeration type giving symbolic names + to all implemented operations. These names are given as parameters + to functions concerning operations in \Ref{Tile} and + \Ref{BaseType}. The selection of operations is actually done in + functions of this class, called by the classes mentioned above. The + operations are implemented in subclasses of \Ref{CondenseOp}, + \Ref{UnaryOp} and \Ref{BinaryOp}. + + The operations in the following table are defined at the moment. + They can be used in expressions like {\tt Ops::OP_EQUAL}. + + \begin{tabular}{cl} + + symbolic name && operation \\ + + && {\bf condense operations} \\ + OP_SOME && condense boolean tile with OR \\ + OP_ALL && condense boolean tile with AND \\ + + && {\bf unary operations} \\ + OP_NOT && negation (bitwise for ints, logical for bools) \\ + OP_SQRT && square root (for doubles) \\ + OP_IDENTITY && used for copying cells \\ + + && {\bf binary operations} \\ + OP_MINUS && subtraction \\ + OP_PLUS && addition \\ + OP_MULT && multiplication \\ + OP_DIV && division \\ + OP_IS && not implemented yet \\ + OP_AND && bitwise resp. logical AND \\ + OP_OR && bitwise resp. logical OR \\ + OP_XOR && bitwise resp. logical XOR \\ + OP_EQUAL && equality (result Bool) \\ + OP_LESS && less than (result Bool) \\ + OP_LESSEQUAL && less than or equal (result Bool) \\ + OP_NOTEQUAL && inequality (result Bool) \\ + OP_GREATER && greater than (result Bool) \\ + OP_GREATEREQUAL && greater than or equal (result Bool) \\ + + \end{tabular} +*/ + +class Ops +{ +public: + enum OpType + { + // condense operations. + OP_COUNT, OP_MAX, OP_MIN, OP_SUM, OP_SOME, + /* insert new condense ops before this line */ OP_ALL, + // unary operations. + OP_NOT, + + //******************* + OP_UFUNC_BEGIN, + OP_ABS, OP_SQRT, + OP_EXP, OP_LOG, OP_LN, + OP_SIN, OP_COS, OP_TAN, + OP_SINH, OP_COSH, OP_TANH, + OP_ARCSIN, OP_ARCCOS, OP_ARCTAN, + OP_UFUNC_END, + + OP_REALPART, + OP_IMAGINARPART, + + OP_CAST_BEGIN, + OP_CAST_BOOL, + OP_CAST_CHAR, + OP_CAST_OCTET, + OP_CAST_SHORT, + OP_CAST_USHORT, + OP_CAST_LONG, + OP_CAST_ULONG, + OP_CAST_FLOAT, + OP_CAST_DOUBLE, + OP_CAST_END, + //******************* + + /* insert new unary ops before this line */ OP_IDENTITY, + // binary operations. + OP_MINUS, OP_PLUS, OP_DIV, OP_MULT, + OP_IS, OP_AND, OP_OR, OP_OVERLAY, OP_BIT, OP_XOR, + /* insert new binary ops before this line */ + OP_EQUAL, OP_LESS, OP_LESSEQUAL, + OP_NOTEQUAL, OP_GREATER, OP_GREATEREQUAL + + }; + + +//@Man: methods for getting functions +//@{ + /// get function object for unary operation. + static UnaryOp* getUnaryOp( Ops::OpType op, const BaseType* restype, + const BaseType* optype, unsigned int resOff = 0, + unsigned int opOff = 0 ); + /*@Doc: + An \Ref{UnaryOp} carrying out #op# on the given types is + returned. If #op# is not applicable to the given types, + 0 is returned. + */ + /// get function object for binary operation. + static BinaryOp* getBinaryOp( Ops::OpType op, const BaseType* resType, + const BaseType* op1Type, const BaseType* op2Type, + unsigned int resOff = 0, + unsigned int op1Off = 0, + unsigned int op2Off = 0 ); + /*@Doc: + An \Ref{BinaryOp} carrying out #op# on the given types is + returned. If #op# is not applicable to the given types, + 0 is returned. + */ + static CondenseOp* getCondenseOp( Ops::OpType op, const BaseType* resType, + const BaseType* opType = 0, + unsigned int resOff = 0, + unsigned int opOff = 0); + /// get function object for condense operation. + static CondenseOp* getCondenseOp( Ops::OpType op, const BaseType* resType, + char* newAccu, const BaseType* opType = 0, + unsigned int resOff = 0, + unsigned int opOff = 0 ); + /*@Doc: + An \Ref{CondenseOp} carrying out #op# on the given types is + returned. If #op# is not applicable to the given types, + 0 is returned. + */ +//@} + +//@Man: methods for checking applicability of functions. +//@{ + /// checks, if #op# is applicable on the given types. + static int isApplicable( Ops::OpType op, const BaseType* op1Type, + const BaseType* op2Type = 0 ); + /*@Doc: + For unary or condense operations, just leave out #op2Type# (or + set it to 0). + */ + /// gives back suggested return type for #op# carried out on the given types. + static const BaseType* getResultType( Ops::OpType op, const BaseType* op1, + const BaseType* op2 = 0 ); + /*@Doc: + This usually gives back the "stronger" type of #op1Type# or #op2Type# + (e.g. for a function like OP_PLUS). Usually the operation can also + be applied to another type, loosing information if the type is + "weaker". At the moment, only comparison operations (e.g. OP_EQUAL) + have a well defined return type, which is Bool. No other return type + can be used for these operations. If the operation is not applicable + to the given type, 0 is returned. + */ + /// executes operation on a constant. + static void execUnaryConstOp( Ops::OpType op, const BaseType* resType, + const BaseType* opType, char* res, + const char* op1, unsigned int resOff = 0, + unsigned int opOff = 0 ); + /// executes operation on two constants. + static void execBinaryConstOp( Ops::OpType op, const BaseType* resType, + const BaseType* op1Type, + const BaseType* op2Type, char* res, + const char* op1, const char* op2, + unsigned int resOff = 0, + unsigned int op1Off = 0, + unsigned int op2Off = 0 ); +//@} + +private: + /// checks, if #op# is applicable on two struct of type opType. + static int isApplicableOnStruct( Ops::OpType op, const BaseType* opType ); + /*@ManMemo: checks, if #op# is applicable on struct of type op1Type + and value of type op2Type.*/ + static int isApplicableOnStructConst( Ops::OpType op, + const BaseType* op1Type, + const BaseType* op2Type ); + /// returns 1 for signed types, 0 for unsigned. + static int isSignedType( const BaseType* type ); + // these functions aren't even used for the time being, but may + // be important for better implementations of isApplicable and + // getResultType. + static int isCondenseOp( Ops::OpType op ); + static int isUnaryOp( Ops::OpType op ); + static int isBinaryOp( Ops::OpType op ); +}; + +//@ManMemo: Module: {\bf catalogif}. + +/*@Doc: + CondenseOp is the superclass for all condense operations. The + operator() carries out a condense operation on one cell {\tt op}, + which is accumulated into {\tt accu}. {\tt accu} is returned as a + result. Remember to always initialize {\tt accu} correctly according + to the condense operation used (e.g. 0 for \Ref{OpSOMEBool} or 1 for + \Ref{OpALLBool}). +*/ + +class CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + CondenseOp( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /*@ManMemo: constructor gets RasDaMan base type of result and operand, + initial value, and offsets to result and operand (for structs) . */ + CondenseOp( const BaseType* newResType, char* newAccu, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ) = 0; + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ) = 0; + /// operator to access value of internal accumulator. + virtual char* getAccuVal(); + /*@ManMemo: virtual destructor because subclasse OpCondenseStruct has + non-trivial destructor. */ + virtual ~CondenseOp(); + +protected: + char* accu; + const BaseType* opType; + const BaseType* resType; + unsigned int resOff; + unsigned int opOff; +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_SOME on C type #char#. + +class OpSOMECChar : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpSOMECChar( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpSOMECChar( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_ALL on C type #char#. + +class OpALLCChar : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpALLCChar( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpALLCChar( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_COUNT on C type #char#. + +class OpCOUNTCChar : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpCOUNTCChar( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpCOUNTCChar( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MAX on C type #char#. + +class OpMAXCULong : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpMAXCULong( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpMAXCULong( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MAX on C type #char#. + +class OpMAXCLong : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpMAXCLong( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpMAXCLong( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MAX on C type #char#. + +class OpMAXCDouble : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpMAXCDouble( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpMAXCDouble( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MIN on C type #char#. + +class OpMINCULong : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpMINCULong( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpMINCULong( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MIN on C type #char#. + +class OpMINCLong : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpMINCLong( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpMINCLong( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MIN on C type #char#. + +class OpMINCDouble : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpMINCDouble( const BaseType* newResType, const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpMINCDouble( const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_SUM on C type #char#. + +class OpSUMCULong : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpSUMCULong(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpSUMCULong(const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_SUM on C type #char#. + +class OpSUMCLong : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpSUMCLong(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpSUMCLong(const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_SUM on C type #char#. + +class OpSUMCDouble : public CondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + OpSUMCDouble(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// constructor initializing internal accu. + OpSUMCDouble(const BaseType* newResType, char* newAccu, + const BaseType* newOpType, unsigned int newResOff, + unsigned int newOpOff ); + /// operator to carry out operation on {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on {\tt op} using internal accu. + virtual char* operator()( const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: Class for carrying out condense operations on structs. + +// Inherits some useless members from CondenseOp, don't want to +// change this now. +class OpCondenseStruct : public CondenseOp +{ +public: + /// constructor gets struct type. + OpCondenseStruct( + const BaseType* newResType, + const BaseType* newOpType, + Ops::OpType op, + unsigned int newResOff = 0, unsigned int newOpOff = 0 + ); + /// constructor gets struct type and initial value for internal accu. + OpCondenseStruct( + const BaseType* newResType, + char* newAccu, + const BaseType* newOpType, + Ops::OpType op, + unsigned int newResOff, + unsigned int newOpOff + ); + /// destructor. + virtual ~OpCondenseStruct(); + /// operator to carry out operation on struct {\tt op}. + virtual char* operator()( const char* op, char* myAccu ); + /// operator to carry out operation on struct {\tt op} using internal accu. + virtual char* operator()( const char* op ); +protected: + StructType* myResType; + StructType* myOpType; + unsigned int numElems; + // array of operations on the elements. + CondenseOp** elemOps; +}; + +//@ManMemo: Module: {\bf catalogif}. + +/*@Doc: + UnaryOp is the superclass for all unary operations. The + operator() carries out a unary operation on one cell {\tt op} and + stores the result in the cell {\tt result}. +*/ + +class UnaryOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operand + and offsets to result and operand (for structs). */ + UnaryOp(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op}. + virtual void operator()( char* result, const char* op ) = 0; + /*@ManMemo: virtual destructor because subclasse OpUnaryStruct has + non-trivial destructor. */ + virtual ~UnaryOp() { }; + +protected: + const BaseType* opType; + const BaseType* resType; + unsigned int resOff; + unsigned int opOff; +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: Class for carrying out binary operations on structs. + +// Inherits some useless members from UnaryOp, don't want to +// change this now. +class OpUnaryStruct : public UnaryOp +{ +public: + /// constructor gets struct type. + OpUnaryStruct( + const BaseType* newResType, + const BaseType* newOpType, + Ops::OpType op, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + /// destructor. + virtual ~OpUnaryStruct(); + /// operator to carry out operation on struct {\tt op}. + virtual void operator()( char* result, const char* op ); + +protected: + StructType* myResType; + StructType* myOpType; + unsigned int numElems; + // array of operations on the elements. + UnaryOp** elemOps; +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_IDENTITY on structs. Works, if struct types are identical. + +class OpIDENTITYStruct : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpIDENTITYStruct(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_NOT on C type #unsigned long#, result #unsigned long#. + +class OpNOTCULong : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpNOTCULong(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_IDENTITY on C type #unsigned long#, result #unsigned long#. + +class OpIDENTITYCULong : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpIDENTITYCULong(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_NOT on C type #unsigned long#, result #unsigned long#. + +class OpNOTCLong : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpNOTCLong(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_NOT on Bools (logical NOT as opposed to bitwise NOT). + +class OpNOTBool : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpNOTBool(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_IDENTITY on C type #unsigned long#, result #unsigned long#. + +class OpIDENTITYCLong : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpIDENTITYCLong(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_IDENTITY on C type #unsigned long#, result #unsigned long#. + +class OpIDENTITYCDouble : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpIDENTITYCDouble(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +/*@Doc: + BinaryOp is the superclass for all binary operations. The operator() + carries out a binary operation on cells {\tt op1} and {\tt op2}. The + result is stored in the cell {\tt res}. +*/ + +class BinaryOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and operands + and offsets to result and operands (for structs). */ + BinaryOp(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ) = 0; + /// returns initialization value for {\ref GenCondenseOp}. + virtual void getCondenseInit(char* init); + /*@ManMemo: virtual destructor because subclasse OpBinaryStruct has + non-trivial destructor. */ + virtual ~BinaryOp() { }; + +protected: + const BaseType* op1Type; + const BaseType* op2Type; + const BaseType* resType; + unsigned int resOff; + unsigned int op1Off; + unsigned int op2Off; +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: Class for carrying out binary operations on structs. + +// Inherits some useless members from BinaryOp, don't want to +// change this now. +class OpBinaryStruct : public BinaryOp +{ +public: + /// constructor gets struct type. + OpBinaryStruct(const BaseType* newStructType, Ops::OpType op, + unsigned int newResOff = 0, unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /// destructor. + virtual ~OpBinaryStruct(); + /// operator to carry out operation on struct {\tt op}. + virtual void operator()( char* res, const char* op1, + const char* op2 ); +protected: + StructType* myStructType; + unsigned int numElems; + // array of operations on the elements. + BinaryOp** elemOps; +}; + +//@ManMemo: Module: {\bf catalogif}. +/*@Doc: Class for carrying out binary operations on structs where the + second operand is a value. */ + +class OpBinaryStructConst : public BinaryOp +{ +public: + /// constructor gets struct type. + OpBinaryStructConst( + const BaseType* resType, + const BaseType* op1Type, + const BaseType* op2Type, + Ops::OpType op, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /// destructor. + virtual ~OpBinaryStructConst(); + /// operator to carry out operation on struct {\tt op}. + virtual void operator()( char* res, const char* op1, + const char* op2 ); +protected: + StructType* resStructType; + StructType* opStructType; + unsigned int numElems; + // array of operations on the elements. + BinaryOp** elemOps; +}; + +//@ManMemo: Module: {\bf catalogif}. +/*@Doc: Class for carrying out binary operations on structs where the + first operand is a value. */ + +class OpBinaryConstStruct : public BinaryOp +{ +public: + /// constructor gets struct type. + OpBinaryConstStruct( + const BaseType* resType, + const BaseType* op1Type, + const BaseType* op2Type, + Ops::OpType op, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /// destructor. + virtual ~OpBinaryConstStruct(); + /// operator to carry out operation on struct {\tt op}. + virtual void operator()( char* res, const char* op1, + const char* op2 ); +protected: + StructType* resStructType; + StructType* opStructType; + unsigned int numElems; + // array of operations on the elements. + BinaryOp** elemOps; +}; + +class OpEQUALStruct : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpEQUALStruct(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /// destructor. + virtual ~OpEQUALStruct(); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +protected: + unsigned int numElems; + // array of operations on the elements. + BinaryOp** elemOps; +}; + +class OpNOTEQUALStruct : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpNOTEQUALStruct(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /// destructor. + virtual ~OpNOTEQUALStruct(); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +protected: + unsigned int numElems; + // array of operations on the elements. + BinaryOp** elemOps; +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_PLUS on C type #unsigned long# and #unsigned long#, result #unsigned long#. + +class OpPLUSCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpPLUSCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +class OpPLUSULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpPLUSULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MINUS on C type #unsigned long# and #unsigned long#, result #unsigned long#. + +class OpMINUSCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpMINUSCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_DIV on C type #unsigned long# and #unsigned long#, result #unsigned long#. + +class OpDIVCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpDIVCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MULT on C type #unsigned long# and #unsigned long#, result #unsigned long#. + +class OpMULTCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpMULTCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_AND on C type #unsigned long# and #unsigned long#, result #unsigned long#. + +class OpANDCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpANDCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_AND on Bools (logical as opposed to bitwise) + +class OpANDBool : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpANDBool(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_OR on C type #unsigned long# and #unsigned long#, result #unsigned long#. + +class OpORCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpORCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_OR on Bools (logical as opposed to bitwise) + +class OpORBool : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpORBool(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_XOR on C type #unsigned long# and #unsigned long#, result #unsigned long#. + +class OpXORCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpXORCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_XOR on Bools (logical as opposed to bitwise) + +class OpXORBool : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpXORBool(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_PLUS on C type #long# and #long#, result #long#. + +class OpPLUSCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpPLUSCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MINUS on C type #long# and #long#, result #long#. + +class OpMINUSCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpMINUSCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_DIV on C type #long# and #long#, result #long#. + +class OpDIVCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpDIVCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MULT on C type #long# and #long#, result #long#. + +class OpMULTCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpMULTCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_AND on C type #long# and #long#, result #long#. + +class OpANDCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpANDCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_OR on C type #long# and #long#, result #long#. + +class OpORCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpORCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_XOR on C type #long# and #long#, result #long#. + +class OpXORCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpXORCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_PLUS on C type #double# and #double#, result #double#. + +class OpPLUSCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpPLUSCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MINUS on C type #double# and #double#, result #double#. + +class OpMINUSCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpMINUSCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_DIV on C type #double# and #double#, result #double#. + +class OpDIVCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpDIVCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MULT on C type #double# and #double#, result #double#. + +class OpMULTCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpMULTCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_EQUAL on C type #unsigned long# and #unsigned long#, result #char#. + +class OpEQUALCCharCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpEQUALCCharCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_LESS on C type #unsigned long# and #unsigned long#, result #char#. + +class OpLESSCCharCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpLESSCCharCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_LESSEQUAL on C type #unsigned long# and #unsigned long#, result #char#. + +class OpLESSEQUALCCharCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpLESSEQUALCCharCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_NOTEQUAL on C type #unsigned long# and #unsigned long#, result #char#. + +class OpNOTEQUALCCharCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpNOTEQUALCCharCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_GREATER on C type #unsigned long# and #unsigned long#, result #char#. + +class OpGREATERCCharCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpGREATERCCharCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_GREATEREQUAL on \Ref{ULong} and \Ref{ULong}, result \Ref{Bool}. + +class OpGREATEREQUALCCharCULong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpGREATEREQUALCCharCULong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_EQUAL on C type #unsigned long# and #unsigned long#, result #char#. + +class OpEQUALCCharCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpEQUALCCharCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_LESS on C type #long# and #long#, result #char#. + +class OpLESSCCharCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpLESSCCharCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_LESSEQUAL on C type #long# and #long#, result #char#. + +class OpLESSEQUALCCharCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpLESSEQUALCCharCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_NOTEQUAL on C type #long# and #long#, result #char#. + +class OpNOTEQUALCCharCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpNOTEQUALCCharCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_GREATER on C type #long# and #long#, result #char#. + +class OpGREATERCCharCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpGREATERCCharCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_GREATEREQUAL on C type #long# and #long#, result #char#. + +class OpGREATEREQUALCCharCLong : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpGREATEREQUALCCharCLong(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_EQUAL on C type #double# and #double#, result #char#. + +class OpEQUALCCharCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpEQUALCCharCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_LESS on C type #double# and #double#, result #char#. + +class OpLESSCCharCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpLESSCCharCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_LESSEQUAL on C type #double# and #double#, result #char#. + +class OpLESSEQUALCCharCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpLESSEQUALCCharCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_NOTEQUAL on C type #double# and #double#, result #char#. + +class OpNOTEQUALCCharCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpNOTEQUALCCharCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_GREATER on C type #double# and #double#, result #char#. + +class OpGREATERCCharCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpGREATERCCharCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_GREATEREQUAL on C type #double# and #double#, result #char#. + +class OpGREATEREQUALCCharCDouble : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpGREATEREQUALCCharCDouble(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_PLUS specialized for RasDaMan type Char. + +class OpPLUSChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpPLUSChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MINUS specialized for RasDaMan type Char. + +class OpMINUSChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpMINUSChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_MULT specialized for RasDaMan type Char. + +class OpMULTChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpMULTChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); + virtual void getCondenseInit(char* init); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_DIV specialized for RasDaMan type Char. + +class OpDIVChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpDIVChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_EQUAL specialized for RasDaMan type Char. + +class OpEQUALChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpEQUALChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_LESS specialized for RasDaMan type Char. + +class OpLESSChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpLESSChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_LESSEQUAL specialized for RasDaMan type Char. + +class OpLESSEQUALChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpLESSEQUALChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_NOTEQUAL specialized for RasDaMan type Char. + +class OpNOTEQUALChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpNOTEQUALChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_GREATER specialized for RasDaMan type Char. + +class OpGREATERChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpGREATERChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_GREATEREQUAL specialized for RasDaMan type Char. + +class OpGREATEREQUALChar : public BinaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operands. + OpGREATEREQUALChar(const BaseType* newResType,const BaseType* newOp1Type, + const BaseType* newOp2Type, unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 ); + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, + const char* op2 ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_IDENTITY specialized for RasDaMan type Char. + +class OpIDENTITYChar : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpIDENTITYChar(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_IDENTITY specialized for RasDaMan type Short. + +class OpIDENTITYShort : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpIDENTITYShort(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_IDENTITY specialized for RasDaMan type Long. + +class OpIDENTITYLong : public UnaryOp +{ +public: + /// constructor gets RasDaMan base type of result and operand. + OpIDENTITYLong(const BaseType* newResType,const BaseType* newOpType, + unsigned int newResOff = 0, unsigned int newOpOff = 0 ); + /// operator to carry out operation on {\tt op} with result {\tt result}. + virtual void operator()( char* result, const char* op ); +}; + +//@ManMemo: Module: {\bf catalogif}. + +/*@Doc: + MarrayOp is the superclass for all marray constructors. The class + defined here is just a dummy and will be specialized in another + module. operator() gets an r_Point as a parameter. For a useful + marray constructor operation() will also need to calculate an + expression. +*/ + +class MarrayOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and its + offset (for structs). Subclasses will have additional parameters. */ + MarrayOp(const BaseType* newResType, unsigned int newResOff = 0 ); + /// operator to carry out operation on {\tt p}. Has a dummy implementation. + virtual void operator() ( char* result, const r_Point& p ); + /*@ManMemo: virtual destructor because subclasses may have + non-trivial destructor. */ + virtual ~MarrayOp() { }; + +protected: + const BaseType* resType; + unsigned int resOff; +}; + +//@ManMemo: Module: {\bf catalogif}. + +/*@Doc: + GenCondenseOp is the superclass for all general condense operations. + The class defined here is just a dummy and will be specialized in + another module. operator() gets an r_Point as a parameter. For a useful + marray constructor operation() will also need to calculate an + expression. Every GenCondenseOp has a binary operation which is + used to accumulate the values. If an initVal (of type resType) + is given, it is used as a basis for accumulation. Otherwist a + default initVal is retrieved from {\tt accuOp}. +*/ + +class GenCondenseOp +{ +public: + /*@ManMemo: constructor gets RasDaMan base type of result and its + offset (for structs, 0 if no struct). A binary operation for + accumulation is given and an optional init value. Subclasses + will have additional parameters. Note that newInitVal has to be + deleted by the caller! */ + GenCondenseOp(const BaseType* newResType, unsigned int newResOff, + BinaryOp* newAccuOp, char* newInitVal = 0 ); + /// operator to carry out operation on {\tt p}. Has a dummy implementation. + virtual void operator()( const r_Point& p ); + /// returns binary accumulation op (needed in class {\ref Tile}. + BinaryOp* getAccuOp(); + /// returns result type (needed in class {\ref Tile}. + const BaseType* getResultType(); + /// returns result offset (needed in class {\ref Tile}. + unsigned int getResultOff(); + /// returns accumulated result. + char* getAccuVal(); + /*@ManMemo: virtual destructor because subclasses may have + non-trivial destructor. */ + virtual ~GenCondenseOp(); + +protected: + const BaseType* resType; + unsigned int resOff; + BinaryOp* accuOp; + // initVal is always of RasDaMan-Type restype! + char* initVal; + // used to flag if destructor should delete initVal + int myInitVal; +}; + + +//-------------------------------------------- +// Complex operations +//-------------------------------------------- + +class OpPLUSComplex : public BinaryOp { +public: + // Question: which operand is scalar? + // Answere: NONE, FIRST, SECOND + enum ScalarFlag { NONE, FIRST, SECOND}; + + OpPLUSComplex( + const BaseType* newResType, + const BaseType* newOp1Type, + const BaseType* newOp2Type, + unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0, + ScalarFlag flag = NONE + ); + virtual void operator()(char* res, const char* op1, const char* op2); + virtual void getCondenseInit(char* init); + +protected: + unsigned int op1ReOff; + unsigned int op1ImOff; + unsigned int op2ReOff; + unsigned int op2ImOff; + unsigned int resReOff; + unsigned int resImOff; + ScalarFlag scalarFlag; +}; + +class OpMINUSComplex : public BinaryOp { +public: + // Question: which operand is scalar? + // Answere: NONE, FIRST, SECOND + enum ScalarFlag { NONE, FIRST, SECOND}; + + OpMINUSComplex( + const BaseType* newResType, + const BaseType* newOp1Type, + const BaseType* newOp2Type, + unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0, + ScalarFlag flag = NONE + ); + virtual void operator()(char* res, const char* op1, const char* op2); + +protected: + unsigned int op1ReOff; + unsigned int op1ImOff; + unsigned int op2ReOff; + unsigned int op2ImOff; + unsigned int resReOff; + unsigned int resImOff; + ScalarFlag scalarFlag; +}; + +class OpDIVComplex : public BinaryOp { +public: + // Question: which operand is scalar? + // Answere: NONE, FIRST, SECOND + enum ScalarFlag { NONE, FIRST, SECOND}; + + OpDIVComplex( + const BaseType* newResType, + const BaseType* newOp1Type, + const BaseType* newOp2Type, + unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0, + ScalarFlag flag = NONE + ); + virtual void operator()( char* res, const char* op1, const char* op2 ); + +protected: + unsigned int op1ReOff; + unsigned int op1ImOff; + unsigned int op2ReOff; + unsigned int op2ImOff; + unsigned int resReOff; + unsigned int resImOff; + ScalarFlag scalarFlag; +}; + +class OpMULTComplex : public BinaryOp { +public: + // Question: which operand is scalar? + // Answere: NONE, FIRST, SECOND + enum ScalarFlag { NONE, FIRST, SECOND}; + + OpMULTComplex( + const BaseType* newResType, + const BaseType* newOp1Type, + const BaseType* newOp2Type, + unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0, + ScalarFlag flag = NONE + ); + virtual void operator()( char* res, const char* op1, const char* op2 ); + virtual void getCondenseInit(char* init); + +protected: + unsigned int op1ReOff; + unsigned int op1ImOff; + unsigned int op2ReOff; + unsigned int op2ImOff; + unsigned int resReOff; + unsigned int resImOff; + ScalarFlag scalarFlag; +}; + +class OpIDENTITYComplex : public UnaryOp { +public: + OpIDENTITYComplex(const BaseType* , const BaseType* , unsigned int = 0, unsigned int = 0); + virtual void operator()(char* result, const char* op); +}; + +class OpRealPart : public UnaryOp { +public: + OpRealPart( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); + +private: + unsigned int opReOff; +}; + + +class OpImaginarPart : public UnaryOp { +public: + OpImaginarPart( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + virtual void operator() (char* result, const char* op); + +private: + unsigned int opImOff; +}; + +//-------------------------------------------- +// OpCAST +//-------------------------------------------- +/*@Doc: +OpCAST provide cast operation. +*/ + +class OpCAST : public UnaryOp { +public: + OpCAST( + const BaseType* newResType, + const BaseType* newOpType, + unsigned int newResOff = 0, + unsigned int newOpOff = 0 + ); + /// operator to carry out cast operation. + virtual void operator() (char* result, const char* op); +}; + +//-------------------------------------------- +// OpOVERLAY +//-------------------------------------------- +//@ManMemo: Module: {\bf catalogif}. +//@Doc: OP_OVERLAY + +class OpOVERLAY : public BinaryOp +{ +public: + /// this pattern is only 16 bytes long and empty, if your struct is longer you need to supply your own pattern + static const char* nullPattern; + /// constructor gets RasDaMan base type of result and operands. + OpOVERLAY(const BaseType* newResType, + const BaseType* newOp1Type, + const BaseType* newOp2Type, + size_t typeSize, + const char* transparentPattern = OpOVERLAY::nullPattern, + unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0); + + /*@ManMemo: operator to carry out operation on {\tt op1} and + {\tt op2} with result {\tt res}. */ + virtual void operator()( char* res, const char* op1, const char* op2 ); +private: + size_t length; + + const char* pattern; +}; + + +//-------------------------------------------- +// OpBIT +//-------------------------------------------- +/*@Doc: +*/ + +class OpBIT : public BinaryOp { +public: + OpBIT( + const BaseType* newResType, + const BaseType* newOp1Type, + const BaseType* newOp2Type, + unsigned int newResOff = 0, + unsigned int newOp1Off = 0, + unsigned int newOp2Off = 0 + ); + + /// operator to carry out bit operation + virtual void operator()(char* res, const char* op1, const char* op2); +}; + + + +#include "autogen_ops.hh" + + +#endif +// LocalWords: op diff --git a/catalogmgr/test/Makefile b/catalogmgr/test/Makefile new file mode 100644 index 0000000..7671ac5 --- /dev/null +++ b/catalogmgr/test/Makefile @@ -0,0 +1,58 @@ +# -*-Makefile-*- +# +# 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 . +# +# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +# rasdaman GmbH. +# +# For more information please see +# or contact Peter Baumann via . # Top Level makefile. This points to the various modules that have to be build +# and/or deployed +# + +# MAKEFILE FOR: +# the test program for a module +# +# COMMENTS: +# List environment dependencies, known bugs, specialities etc. +# +################################################################## + +# +# This is just an example Makefile for a test program. +# The dependency of the test program on the lib of the +# corresponding module is in the Makefile of the module. +# + +######################### Definitions ############################ + +# standard include with general options +include $(RMANBASE)/Makefile.inc + +# object files for test program +OBJS = +# name of test program +ALLTESTS = + +MISCCLEAN := core + +########################### Targets ############################## + +# general rules +include $(RMANBASE)/Makefile.rel + +# automatically created dependencies +include Makefile.dep diff --git a/catalogmgr/typefactory.cc b/catalogmgr/typefactory.cc new file mode 100644 index 0000000..80fee7a --- /dev/null +++ b/catalogmgr/typefactory.cc @@ -0,0 +1,626 @@ +/* +* 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 . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +// This is -*- C++ -*- +/************************************************************************* + * + * + * PURPOSE: + * + * + * COMMENTS: + * uses embedded SQL + * + ***********************************************************************/ + +static const char rcsid[] = "@(#)catalogif,TypeFactory: $Header: /home/rasdev/CVS-repository/rasdaman/catalogmgr/typefactory.cc,v 1.19 2003/12/20 23:41:27 rasdev Exp $"; + +#include +#include +#include +#include +#include + +#include "raslib/rminit.hh" +#include "raslib/rmdebug.hh" +#include "relcatalogif/alltypes.hh" +#include "typefactory.hh" +#include "reladminif/objectbroker.hh" +#include "reladminif/adminif.hh" +#include "reladminif/databaseif.hh" +#include "reladminif/sqlerror.hh" +#include "reladminif/externs.h" +#include "reladminif/dbref.hh" +#include "relcatalogif/dbminterval.hh" +#include "relmddif/mddid.hh" +#include "relmddif/dbmddobj.hh" +#include "relmddif/dbmddset.hh" + +TypeFactory* TypeFactory::myInstance = 0; + +const short TypeFactory::MaxBuiltInId = 11; + +const char* OctetType::Name = "Octet"; +const char* UShortType::Name = "UShort"; +const char* ShortType::Name = "Short"; +const char* ULongType::Name = "ULong"; +const char* LongType::Name = "Long"; +const char* BoolType::Name = "Bool"; +const char* CharType::Name = "Char"; +const char* FloatType::Name = "Float"; +const char* DoubleType::Name = "Double"; +const char* ComplexType1::Name = "Complex1"; +const char* ComplexType2::Name = "Complex2"; + +using namespace std; + +// all atomic types given back by mapType() +// for managing the memory of temporary types +std::vector *TypeFactory::theTempTypes = 0; + +TypeFactory* +TypeFactory::instance() + { + if(myInstance == 0) + { + myInstance = new TypeFactory; + } + return myInstance; + } + +const BaseType* +TypeFactory::mapType(const char* typeName) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "mapType(" << typeName << ")"); + BaseType* resultType = 0; + resultType = (BaseType*)ObjectBroker::getObjectByName(OId::ATOMICTYPEOID, typeName); + if (resultType == 0) + { + try { + resultType = (BaseType*)ObjectBroker::getObjectByName(OId::STRUCTTYPEOID, typeName); + } + catch (r_Error) + { + resultType = 0; + } + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "mapType(" << typeName << ") END " << resultType); + return resultType; + } + +const StructType* +TypeFactory::addStructType(const StructType* type) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "addStructType(" << type->getTypeName() << ")"); + StructType* persistentType = 0; + const StructType* retval = 0; + if (type->isPersistent()) + { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "type is persistent " << type->getName() << " " << type->getOId()); + retval = type; + } + else { + persistentType = new StructType((char*)type->getTypeName(), type->getNumElems()); + BaseType* t = 0; + for (int i = 0; i < type->getNumElems(); i++) + { + switch (type->getElemType(i)->getType()) + { + case STRUCT: + RMDBGMIDDLE(6, RMDebug::module_catalogmgr, "TypeFactory", "element is struct type " << (char*)type->getElemName(i) << " of type " << type->getElemType(i)->getName()); + persistentType->addElement(type->getElemName(i), addStructType((const StructType*)type->getElemType(i))); + break; + case ULONG: + case USHORT: + case CHAR: + case BOOLTYPE: + case LONG: + case SHORT: + case OCTET: + case DOUBLE: + case FLOAT: + case COMPLEXTYPE1: + case COMPLEXTYPE2: + RMDBGMIDDLE(6, RMDebug::module_catalogmgr, "TypeFactory", "element is atomic type " << (char*)type->getElemName(i) << " of type " << type->getElemType(i)->getName()); + persistentType->addElement(type->getElemName(i), (BaseType*)ObjectBroker::getObjectByOId(type->getElemType(i)->getOId())); + break; + default: + persistentType = 0; + RMDBGMIDDLE(0, RMDebug::module_catalogmgr, "TypeFactory", "addStructType(" << type->getTypeName() << ") unknown type " << type->getOId() << type->getOId().getType()); + break; + } + } + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "type is now persistent " << persistentType->getName() << " " << persistentType->getOId()); + persistentType->setCached(true); + persistentType->setPersistent(true); + ObjectBroker::registerDBObject(persistentType); + retval = persistentType; + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "addStructType(" << retval->getTypeName() << ") END"); + return retval; + } + +const SetType* +TypeFactory::mapSetType(const char* typeName) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "mapSetType(" << typeName << ")"); + // it is a user defined type + SetType* resultType = 0; + try { + resultType = (SetType*)ObjectBroker::getObjectByName(OId::SETTYPEOID, typeName); + } + catch (r_Error) + { + resultType = 0; + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "mapSetType(" << typeName << ") END " << resultType); + return resultType; + } + +const SetType* +TypeFactory::addSetType(const SetType* type) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "addSetType(" << type->getTypeName() << ")"); + SetType* persistentType = 0; + const SetType* retval = 0; + if (type->isPersistent()) + { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "type is persistent " << type->getName() << " " << type->getOId()); + retval = type; + } + else { + persistentType = new SetType((char*)type->getTypeName(), addMDDType(type->getMDDType())); + persistentType->setPersistent(true); + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "type is now persistent " << type->getName() << " " << persistentType->getOId()); + ObjectBroker::registerDBObject(persistentType); + persistentType->setCached(true); + retval = persistentType; + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "addSetType(" << retval->getTypeName() << ") END"); + return retval; + } + +const MDDType* +TypeFactory::mapMDDType(const char* typeName) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "mapMDDType(" << typeName << ")"); + MDDType* resultType = 0; + try { + resultType = ObjectBroker::getMDDTypeByName(typeName); + } + catch (...) + { + resultType = 0; + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "mapMDDType(" << typeName << ") END " << resultType); + return resultType; + } + +const MDDType* +TypeFactory::addMDDType(const MDDType* type) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "addMDDType(" << type->getTypeName() << ")"); + MDDType* persistentType = 0; + const MDDType* retval = 0; + BaseType* t = 0; + + if (type->isPersistent()) + { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "type is persistent " << type->getOId()); + retval = type; + } + else { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "type is not persistent " << type->getOId()); + switch (type->getSubtype()) + { + case MDDType::MDDONLYTYPE: + RMDBGMIDDLE(7, RMDebug::module_catalogmgr, "TypeFactory", "is MDDONLYTYPE"); + persistentType = new MDDType(type->getTypeName()); + break; + case MDDType::MDDBASETYPE: + RMDBGMIDDLE(7, RMDebug::module_catalogmgr, "TypeFactory", "is MDDBASETYPE"); + persistentType = new MDDBaseType(type->getTypeName(), addStructType((StructType*)((MDDBaseType*)type)->getBaseType())); + break; + case MDDType::MDDDOMAINTYPE: + RMDBGMIDDLE(7, RMDebug::module_catalogmgr, "TypeFactory", "is MDDDOMAINTYPE"); + persistentType = new MDDDomainType(type->getTypeName(), addStructType((StructType*)((MDDBaseType*)type)->getBaseType()), *((MDDDomainType*)type)->getDomain()); + break; + case MDDType::MDDDIMENSIONTYPE: + RMDBGMIDDLE(7, RMDebug::module_catalogmgr, "TypeFactory", "is MDDDIMENSIONTYPE"); + persistentType = new MDDDimensionType(type->getTypeName(), addStructType((StructType*)((MDDBaseType*)type)->getBaseType()), ((MDDDimensionType*)type)->getDimension()); + break; + default: + RMDBGMIDDLE(0, RMDebug::module_catalogmgr, "TypeFactory", "addMDDType(" << type->getName() << ") mddsubtype unknown"); + break; + } + if (persistentType != 0) + { + persistentType->setPersistent(true); + RMDBGMIDDLE(6, RMDebug::module_catalogmgr, "TypeFactory", "adding " << persistentType->getName() << " " << persistentType->getOId()); + persistentType->setCached(true); + ObjectBroker::registerDBObject(persistentType); + retval = persistentType; + } + else { + //error message was already given in switch default + } + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "addMDDType(" << type->getTypeName() << ") END"); + return retval; + } + +Type* +TypeFactory::addTempType(Type* type) + { + // put in front to avoid deletion of MDDTypes still referenced + // by an MDDBaseType. + theTempTypes->insert(theTempTypes->begin(), type); + return type; + } + +void +TypeFactory::initialize() + { + // to initailize the typefactory + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "initialize()"); + if (!theTempTypes) + theTempTypes = new std::vector; + + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "initialize() END"); + } + +void +TypeFactory::freeTempTypes() + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "freeTempTypes()"); + + // delete all temporary types + if (theTempTypes) + { + for(std::vector::iterator iter = theTempTypes->begin(); iter != theTempTypes->end(); iter++) + { + delete *iter; + *iter = 0; + } + delete theTempTypes; + theTempTypes = 0; + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "freeTempTypes()"); + } + +TypeFactory::TypeFactory() + { + } + +void +TypeFactory::deleteStructType(const char* typeName) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "deleteStructType(" << typeName << ")"); + const DBObject* resultType = mapType(typeName); + if (resultType) + { + if (resultType->getOId().getCounter() > MaxBuiltInId) + {//only neccessary to check if the type is in a mdd base/dim/dom type + bool canDelete = true; + for (TypeIterator miter = createMDDIter(); miter.not_done(); miter.advance()) + { + if (miter.get_element()->getSubtype() != MDDType::MDDONLYTYPE) + { + if (((MDDBaseType*)(miter.get_element().ptr()))->getBaseType() == resultType) + { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "mdd type " << miter.get_element()->getName() << " contains " << typeName); + canDelete = false; + break; + } + } + } + if (canDelete) + { + DBObjectId toKill(resultType->getOId()); + toKill->setPersistent(false); + toKill->setCached(false); + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "will be deleted from db"); + } + else { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "will not be deleted from db"); + } + } + else { + RMDBGMIDDLE(0, RMDebug::module_catalogmgr, "TypeFactory", "builtin type will not be deleted"); + } + } + else { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "is not in map"); + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "deleteStructType(" << typeName << ")"); + } + +void +TypeFactory::deleteMDDType(const char* typeName) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "deleteMDDType(" << typeName << ")"); + const MDDType* resultType = mapMDDType(typeName); //is ok because only short for find + if (resultType) + { + bool canDelete = true; + for (TypeIterator miter = createSetIter(); miter.not_done(); miter.advance()) + { + if (miter.get_element()->getMDDType() == resultType) + { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "set type " << miter.get_element()->getName() << " contains " << typeName); + canDelete = false; + break; + } + } + if (canDelete) + { + if (resultType->getSubtype() != MDDType::MDDONLYTYPE) + { + //mdd only types can not be in mdd objects + OIdSet* theList = ObjectBroker::getAllObjects(OId::MDDOID); + for (OIdSet::iterator miter = theList->begin(); miter != theList->end(); miter++) + { + if (DBMDDObjId(*miter)->getMDDBaseType() == resultType) + { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "mdd object " << *miter << " contains " << typeName); + canDelete = false; + break; + } + } + delete theList; + theList = 0; + } + if (canDelete) + { + DBObjectId toKill(resultType->getOId()); + toKill->setPersistent(false); + toKill->setCached(false); + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "will be deleted from db"); + } + else { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "will not be deleted from db"); + } + } + else { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "will not be deleted from db"); + } + } + else { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "is not in map"); + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "deleteMDDType(" << typeName << ") END"); + } + +void +TypeFactory::deleteSetType(const char* typeName) + { + RMDBGENTER(4, RMDebug::module_catalogmgr, "TypeFactory", "deleteSetType(" << typeName << ")"); + const DBObject* resultType = (SetType*)mapSetType(typeName);//is ok because only short for find + if (resultType) + { + bool canDelete = true; + OIdSet* theList = ObjectBroker::getAllObjects(OId::MDDCOLLOID); + for (OIdSet::iterator miter = theList->begin(); miter != theList->end(); miter++) + { + if (DBMDDSetId(*miter)->getCollType() == resultType) + { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "set object " << *miter << " contains " << typeName); + canDelete = false; + break; + } + } + delete theList; + theList = 0; + if (canDelete) + { + DBObjectId toKill(resultType->getOId()); + toKill->setPersistent(false); + toKill->setCached(false); + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "will be deleted from db"); + } + else { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "will not be deleted from db"); + } + } + else { + RMDBGMIDDLE(5, RMDebug::module_catalogmgr, "TypeFactory", "is not in map"); + } + RMDBGEXIT(4, RMDebug::module_catalogmgr, "TypeFactory", "deleteSetType(" << typeName << ") END"); + } + +const Type* +TypeFactory::ensurePersistence(Type* type) + { + std::vector::iterator iter; + const Type* retval = 0; + Type* ttype = 0; + + // deleting type if it is in the list of tempTypes + if(theTempTypes) + { + for(iter = theTempTypes->begin(); iter < theTempTypes->end(); iter++) + { + if(*iter == type) + { + theTempTypes->erase(iter); + } + } + } + // check if the struct type is alread in the DBMS + switch (type->getType()) + { + case STRUCT: + { + TypeIterator ist = createStructIter(); + while (ist.not_done()) + { + ttype = ist.get_element(); + if (ttype->compatibleWith(type)) + { + retval = ttype; + break; + } + ist.advance(); + } + if (!retval) + retval = addStructType((const StructType*)type); + } + break; + case MDDTYPE: + { + TypeIterator imd = createMDDIter(); + while (imd.not_done()) + { + ttype = imd.get_element(); + if (ttype->compatibleWith(type)) + { + retval = ttype; + break; + } + imd.advance(); + } + if (!retval) + retval = addMDDType((const MDDType*)type); + } + break; + case SETTYPE: + { + TypeIterator ise = createSetIter(); + while (ise.not_done()) + { + ttype = ise.get_element(); + if (ttype->compatibleWith(type)) + { + retval = ttype; + break; + } + ise.advance(); + } + if (!retval) + retval = addSetType((const SetType*)type); + } + break; + case ULONG: + retval = (Type*)ObjectBroker::getObjectByOId(OId(ULONG, OId::ATOMICTYPEOID)); + break; + case USHORT: + retval = (Type*)ObjectBroker::getObjectByOId(OId(USHORT, OId::ATOMICTYPEOID)); + break; + case CHAR: + retval = (Type*)ObjectBroker::getObjectByOId(OId(CHAR, OId::ATOMICTYPEOID)); + break; + case BOOLTYPE: + retval = (Type*)ObjectBroker::getObjectByOId(OId(BOOLTYPE, OId::ATOMICTYPEOID)); + break; + case LONG: + retval = (Type*)ObjectBroker::getObjectByOId(OId(LONG, OId::ATOMICTYPEOID)); + break; + case SHORT: + retval = (Type*)ObjectBroker::getObjectByOId(OId(SHORT, OId::ATOMICTYPEOID)); + break; + case OCTET: + retval = (Type*)ObjectBroker::getObjectByOId(OId(OCTET, OId::ATOMICTYPEOID)); + break; + case DOUBLE: + retval = (Type*)ObjectBroker::getObjectByOId(OId(DOUBLE, OId::ATOMICTYPEOID)); + break; + case FLOAT: + retval = (Type*)ObjectBroker::getObjectByOId(OId(FLOAT, OId::ATOMICTYPEOID)); + break; + case COMPLEXTYPE1: + retval = (Type*)ObjectBroker::getObjectByOId(OId(COMPLEXTYPE1, OId::ATOMICTYPEOID)); + break; + case COMPLEXTYPE2: + retval = (Type*)ObjectBroker::getObjectByOId(OId(COMPLEXTYPE2, OId::ATOMICTYPEOID)); + break; + default: + RMDBGONCE(0, RMDebug::module_catalogmgr, "TypeFactory", "ensurePersitence() is not a STRUCT/MDDTYPE/SETTYPE/ATOMIC " << type->getName()); + break; + } + if (!type->isPersistent()) + delete type; + return retval; + } + +TypeIterator +TypeFactory::createSetIter() + { + RMDBGONCE(1, RMDebug::module_catalogmgr, "TypeFactory", "createSetIter()"); + OIdSet* t = ObjectBroker::getAllObjects(OId::SETTYPEOID); + TypeIterator ti(*t); + delete t; + t = 0; + return ti; + } + +TypeIterator +TypeFactory::createStructIter() + { + RMDBGONCE(1, RMDebug::module_catalogmgr, "TypeFactory", "createStructIter()"); + OIdSet* t = ObjectBroker::getAllObjects(OId::STRUCTTYPEOID); + TypeIterator ti(*t); + delete t; + t = 0; + return ti; + } + +TypeIterator +TypeFactory::createMDDIter() + { + RMDBGENTER(1, RMDebug::module_catalogmgr, "TypeFactory", "createMDDIter()"); + OIdSet theMDDTypes; + OIdSet* tempList = 0; + OIdSet::iterator i; + + tempList = ObjectBroker::getAllObjects(OId::MDDTYPEOID); + theMDDTypes = *tempList; + delete tempList; + + tempList = ObjectBroker::getAllObjects(OId::MDDBASETYPEOID); + while (!tempList->empty()) + { + theMDDTypes.insert(*(tempList->begin())); + tempList->erase(*(tempList->begin())); + } + delete tempList; + + tempList = ObjectBroker::getAllObjects(OId::MDDDIMTYPEOID); + while (!tempList->empty()) + { + theMDDTypes.insert(*(tempList->begin())); + tempList->erase(*(tempList->begin())); + } + delete tempList; + + tempList = ObjectBroker::getAllObjects(OId::MDDDOMTYPEOID); + while (!tempList->empty()) + { + theMDDTypes.insert(*(tempList->begin())); + tempList->erase(*(tempList->begin())); + } + delete tempList; + + RMDBGEXIT(1, RMDebug::module_catalogmgr, "TypeFactory", "createMDDIter()"); + return TypeIterator(theMDDTypes); + } + + diff --git a/catalogmgr/typefactory.hh b/catalogmgr/typefactory.hh new file mode 100644 index 0000000..816bb2d --- /dev/null +++ b/catalogmgr/typefactory.hh @@ -0,0 +1,262 @@ +/* +* 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 . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +/************************************************************* + * + * + * PURPOSE: + * + * + * COMMENTS: + * + ************************************************************/ + +#ifndef _TYPEFACTORY_HH_ +#define _TYPEFACTORY_HH_ + +class TypeFactory; + +#include +#include + +#include "reladminif/oidif.hh" +#include "relcatalogif/typeiterator.hh" + +class ULongType; +class LongType; +class CharType; +class BoolType; +class UShortType; +class ShortType; +class OctetType; +class DoubleType; +class FloatType; +class ComplexType1; +class ComplexType2; +class StructType; +class BaseType; +class SetType; +class MDDType; +class Type; +class DBMinterval; + +//@ManMemo: Module: {\bf relcatalogif}. + +/*@Doc: + +The user specifies types as strings. This is passed down to the +TypeFactory where according to the string the object representing +the type is read from the database. The base DBMS manages +persistent objects for all base types. Pointers to these +persistent objects are returned if #mapType# is called. In the +current implementation, these pointers get invalid after a +transaction is committed. So the user has to call #mapType# again +after a commit(most programs do this anyway). + +The name of the type used for accessing it is the class name without +the Type suffix. e.g. "Bool" for \Ref{BoolType} or "ULong" for +\Ref{ULongType}. + +Only one instance of TypeFactory exists at any time. Also only one +instance of the types exits in memory. The pointers returned +should not be freed, the memory is freed, when the TypeFactory is +destroyed. The static member function can also be called directly +with the scope operator. The class follows the singleton design +pattern(Gamma et. al. S. 127ff.) and the builder design pattern +(Gamma et. al. S. 97ff.). + +{\bf Functionality} + +Returns a pointer to \Ref{BaseType} to the type which is identified by +a string. + +{\bf Interdependencies} + +Will be used from \Ref{MDDObject} and subclasses when created. +Because all types are stored persistently, it is necessary to open +a session using AdminIf::instance()(see \Ref{AdminIf}), a +database using DatabaseIf::open()(see \Ref{DatabaseIf) and a +transaction using TransactionIf::begin(see \Ref{TransactionIf) +before creating instances of types with mapType(). +*/ + +class TypeFactory + { + public: + static TypeFactory* instance(); + /*@Doc: + used to access instance of TileFactory. + */ + + static const BaseType* mapType(const char* typeName); + /*@Doc: + maps a string to a base type + e.g. #aTypeFactory->mapType("ULong")# returns a pointer to an + instance of ULongType. This also works for user defined type + like #aTypeFactory->mapType("myStruct")# returning a pointer + to a user defined StructType. + */ + + //static BaseType* mapType(char* typeName); + /*@Doc: + maps a string to a base type + use the const char* version!! + */ + + static const SetType* mapSetType(const char* typeName); + /*@Doc: + maps a string to a set type + */ + + //static const SetType* mapSetType(char* typeName); + /*@Doc: + maps a string to a set type + use the const char* version!! + */ + + static const MDDType* mapMDDType(const char* typeName); + /*@Doc: + maps a string to a mdd type + */ + + //static const MDDType* mapMDDType(char* typeName); + /*@Doc: + maps a string to a mdd type. + use the const char* version!! + */ + + static const StructType* addStructType(const StructType* type); + /*@Doc: + add a new struct type to the current DBMS. + After calling this function, a user defined type can be + retrieved with function #mapType()#. The type only becomes + persistent after commit. + */ + + static const SetType* addSetType(const SetType* type); + /*@Doc: + add a new set type to the current DBMS. + After calling this function, a user defined set type can be + retrieved with function #mapSetType()#. The type only becomes + persistent after commit. + */ + + static const MDDType* addMDDType(const MDDType* type); + /*@Doc: + add a new set type to the current DBMS. + After calling this function, a user defined mdd type can be + retrieved with function #mapMDDType()#. The type only becomes + persistent after commit. + */ + + static void deleteStructType(const char* typeName); + /*@Doc: + delete a struct type in the current DBMS. + */ + + static void deleteSetType(const char* typeName); + /*@Doc: + delete a set type in the current DBMS. + */ + + static void deleteMDDType(const char* typeName); + /*@Doc: + delete a mdd type in the current DBMS. + */ + + static TypeIterator createStructIter(); + /*@Doc: + Note that get_element returns a pointer to a StructType! + returns an iterator for StructTypes. + */ + + static TypeIterator createSetIter(); + /*@Doc: + Note that get_element returns a pointer to a SetType! + returns an iterator for SetTypes. + */ + + static TypeIterator createMDDIter(); + /*@Doc: + Note that get_element returns a pointer to a MDDType! + returns an iterator for MDDTypes. + */ + + + static Type* addTempType(Type* type); + /*@Doc: + Memory is freed at commit time of transaction in + TransactionIf::commit(), TransactionIf::validate() and + TransactionIf::abort(). + + {\em Note:} You have to use addTempType() on a composite type + (e.g. \Ref{SetType}) first before calling addTempType() on a + component(e.g. \Ref{MDDType}). Otherwise the component may be + freed first sometimes leading to a crash. + registers a temporary type with the type factory. + */ + + static void initialize(); + /*@Doc: + Should only be called by \Ref{TransactionIf}). + initializes after a begin transaction. theTempTypes are created. + */ + + static void freeTempTypes(); + /*@Doc: + Should only be called by \Ref{TransactionIf}). + frees temporary types. + */ + + static const Type* ensurePersistence(Type* type); + /*@Doc: + This function has to be called on all types registered as + temporary types but getting persistent during query execution. The + type is deleted from the tempTypes list, i.e. not freed on end of + transaction. If a structurally equivalent type is found in the + database it will be used and a pointer to it returned. Note that + this currently works only for StructTypes! + has to be called on temporary types getting persistent. + */ + + static const short MaxBuiltInId; + + protected: + TypeFactory(); + /*@Doc: + constructor, can not be used from outside. + */ + + private: + static TypeFactory* myInstance; + /*@Doc: + pointer to instance for Singleton pattern. + */ + + static std::vector *theTempTypes; + /*@Doc: + a vector containing pointers to temporary allocated types. + */ + + }; + +#endif -- cgit