/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #ifndef SC_JUMPMATRIX_HXX #define SC_JUMPMATRIX_HXX #include "formula/token.hxx" #include "formula/errorcodes.hxx" #include #include #include "scmatrix.hxx" typedef ::std::vector< formula::FormulaToken*> ScTokenVec; struct ScJumpMatrixEntry { double fBool; // 0:= false 1:= true also if no-path // other values may contain error conditions like NAN and INF short nStart; // start of path (actually start-1, see formula::FormulaTokenIterator) short nNext; // next after path // jump path exists if nStart != nNext, else no path short nStop; // optional stop of path (nPC < nStop) void SetJump( double fBoolP, short nStartP, short nNextP, short nStopP ) { fBool = fBoolP; nStart = nStartP; nNext = nNextP; nStop = nStopP; } void GetJump( double& rBool, short& rStart, short& rNext, short& rStop ) { rBool = fBool; rStart = nStart; rNext = nNext; rStop = nStop; } }; class ScJumpMatrix { ScJumpMatrixEntry* pJump; // the jumps ScMatrixRef pMat; // the results ScTokenVec* pParams; // parameter stack SCSIZE nCols; SCSIZE nRows; SCSIZE nCurCol; SCSIZE nCurRow; SCSIZE nResMatCols; SCSIZE nResMatRows; bool bStarted; // not implemented, prevent usage ScJumpMatrix( const ScJumpMatrix& ); ScJumpMatrix& operator=( const ScJumpMatrix& ); public: ScJumpMatrix( SCSIZE nColsP, SCSIZE nRowsP ) : pJump( new ScJumpMatrixEntry[ nColsP * nRowsP ] ) , pMat( new ScMatrix( nColsP, nRowsP) ) , pParams( NULL ) , nCols( nColsP ) , nRows( nRowsP ) , nCurCol( 0 ) , nCurRow( 0 ) , nResMatCols( nColsP ) , nResMatRows( nRowsP ) , bStarted( false ) { // Initialize result matrix in case of // a premature end of the interpreter // due to errors. pMat->FillDouble( CreateDoubleError( NOTAVAILABLE), 0, 0, nCols-1, nRows-1); /*! pJump not initialized */ } ~ScJumpMatrix() { if ( pParams ) { for ( ScTokenVec::iterator i = pParams->begin(); i != pParams->end(); ++i ) { (*i)->DecRef(); } delete pParams; } delete [] pJump; } void GetDimensions( SCSIZE& rCols, SCSIZE& rRows ) const { rCols = nCols; rRows = nRows; } void SetJump( SCSIZE nCol, SCSIZE nRow, double fBool, short nStart, short nNext, short nStop = SHRT_MAX ) { pJump[ (sal_uLong)nCol * nRows + nRow ]. SetJump( fBool, nStart, nNext, nStop); } void GetJump( SCSIZE nCol, SCSIZE nRow, double& rBool, short& rStart, short& rNext, short& rStop ) const { if (nCols == 1 && nRows == 1) { nCol = 0; nRow = 0; } else if (nCols == 1 && nRow < nRows) nCol = 0; else if (nRows == 1 && nCol < nCols) nRow = 0; else if (nCols <= nCol || nRows <= nRow) { DBG_ERROR("ScJumpMatrix::GetJump: dimension error"); nCol = 0; nRow = 0; } pJump[ (sal_uLong)nCol * nRows + nRow ]. GetJump( rBool, rStart, rNext, rStop); } void SetAllJumps( double fBool, short nStart, short nNext, short nStop = SHRT_MAX ) { sal_uLong n = (sal_uLong)nCols * nRows; for ( sal_uLong j=0; j= nResMatRows ) { nCurRow = 0; ++nCurCol; } } GetPos( rCol, rRow ); return nCurCol < nResMatCols; } void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows ) { rCols = nResMatCols; rRows = nResMatRows; } void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows ) { if ( nNewCols > nResMatCols || nNewRows > nResMatRows ) { pMat = pMat->CloneAndExtend( nNewCols, nNewRows ); if ( nResMatCols < nNewCols ) { pMat->FillDouble( CreateDoubleError( NOTAVAILABLE), nResMatCols, 0, nNewCols-1, nResMatRows-1); } if ( nResMatRows < nNewRows ) { pMat->FillDouble( CreateDoubleError( NOTAVAILABLE), 0, nResMatRows, nNewCols-1, nNewRows-1); } if ( nRows == 1 && nCurCol != 0 ) { nCurCol = 0; nCurRow = nResMatRows - 1; } nResMatCols = nNewCols; nResMatRows = nNewRows; } } }; #endif // SC_JUMPMATRIX_HXX