1*38d50f7bSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*38d50f7bSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*38d50f7bSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*38d50f7bSAndrew Rist * distributed with this work for additional information 6*38d50f7bSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*38d50f7bSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*38d50f7bSAndrew Rist * "License"); you may not use this file except in compliance 9*38d50f7bSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*38d50f7bSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*38d50f7bSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*38d50f7bSAndrew Rist * software distributed under the License is distributed on an 15*38d50f7bSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*38d50f7bSAndrew Rist * KIND, either express or implied. See the License for the 17*38d50f7bSAndrew Rist * specific language governing permissions and limitations 18*38d50f7bSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*38d50f7bSAndrew Rist *************************************************************/ 21*38d50f7bSAndrew Rist 22*38d50f7bSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #ifndef SC_JUMPMATRIX_HXX 25cdf0e10cSrcweir #define SC_JUMPMATRIX_HXX 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "formula/token.hxx" 28cdf0e10cSrcweir #include "formula/errorcodes.hxx" 29cdf0e10cSrcweir #include <tools/solar.h> 30cdf0e10cSrcweir #include <vector> 31cdf0e10cSrcweir #include "scmatrix.hxx" 32cdf0e10cSrcweir 33cdf0e10cSrcweir typedef ::std::vector< formula::FormulaToken*> ScTokenVec; 34cdf0e10cSrcweir 35cdf0e10cSrcweir struct ScJumpMatrixEntry 36cdf0e10cSrcweir { 37cdf0e10cSrcweir double fBool; // 0:= false 1:= true also if no-path 38cdf0e10cSrcweir // other values may contain error conditions like NAN and INF 39cdf0e10cSrcweir short nStart; // start of path (actually start-1, see formula::FormulaTokenIterator) 40cdf0e10cSrcweir short nNext; // next after path 41cdf0e10cSrcweir // jump path exists if nStart != nNext, else no path 42cdf0e10cSrcweir short nStop; // optional stop of path (nPC < nStop) 43cdf0e10cSrcweir SetJumpScJumpMatrixEntry44cdf0e10cSrcweir void SetJump( double fBoolP, short nStartP, short nNextP, short nStopP ) 45cdf0e10cSrcweir { 46cdf0e10cSrcweir fBool = fBoolP; 47cdf0e10cSrcweir nStart = nStartP; 48cdf0e10cSrcweir nNext = nNextP; 49cdf0e10cSrcweir nStop = nStopP; 50cdf0e10cSrcweir } GetJumpScJumpMatrixEntry51cdf0e10cSrcweir void GetJump( double& rBool, short& rStart, short& rNext, short& rStop ) 52cdf0e10cSrcweir { 53cdf0e10cSrcweir rBool = fBool; 54cdf0e10cSrcweir rStart = nStart; 55cdf0e10cSrcweir rNext = nNext; 56cdf0e10cSrcweir rStop = nStop; 57cdf0e10cSrcweir } 58cdf0e10cSrcweir }; 59cdf0e10cSrcweir 60cdf0e10cSrcweir class ScJumpMatrix 61cdf0e10cSrcweir { 62cdf0e10cSrcweir ScJumpMatrixEntry* pJump; // the jumps 63cdf0e10cSrcweir ScMatrixRef pMat; // the results 64cdf0e10cSrcweir ScTokenVec* pParams; // parameter stack 65cdf0e10cSrcweir SCSIZE nCols; 66cdf0e10cSrcweir SCSIZE nRows; 67cdf0e10cSrcweir SCSIZE nCurCol; 68cdf0e10cSrcweir SCSIZE nCurRow; 69cdf0e10cSrcweir SCSIZE nResMatCols; 70cdf0e10cSrcweir SCSIZE nResMatRows; 71cdf0e10cSrcweir bool bStarted; 72cdf0e10cSrcweir 73cdf0e10cSrcweir // not implemented, prevent usage 74cdf0e10cSrcweir ScJumpMatrix( const ScJumpMatrix& ); 75cdf0e10cSrcweir ScJumpMatrix& operator=( const ScJumpMatrix& ); 76cdf0e10cSrcweir 77cdf0e10cSrcweir public: ScJumpMatrix(SCSIZE nColsP,SCSIZE nRowsP)78cdf0e10cSrcweir ScJumpMatrix( SCSIZE nColsP, SCSIZE nRowsP ) 79cdf0e10cSrcweir : pJump( new ScJumpMatrixEntry[ nColsP * nRowsP ] ) 80cdf0e10cSrcweir , pMat( new ScMatrix( nColsP, nRowsP) ) 81cdf0e10cSrcweir , pParams( NULL ) 82cdf0e10cSrcweir , nCols( nColsP ) 83cdf0e10cSrcweir , nRows( nRowsP ) 84cdf0e10cSrcweir , nCurCol( 0 ) 85cdf0e10cSrcweir , nCurRow( 0 ) 86cdf0e10cSrcweir , nResMatCols( nColsP ) 87cdf0e10cSrcweir , nResMatRows( nRowsP ) 88cdf0e10cSrcweir , bStarted( false ) 89cdf0e10cSrcweir { 90cdf0e10cSrcweir // Initialize result matrix in case of 91cdf0e10cSrcweir // a premature end of the interpreter 92cdf0e10cSrcweir // due to errors. 93cdf0e10cSrcweir pMat->FillDouble( CreateDoubleError( 94cdf0e10cSrcweir NOTAVAILABLE), 0, 0, nCols-1, 95cdf0e10cSrcweir nRows-1); 96cdf0e10cSrcweir /*! pJump not initialized */ 97cdf0e10cSrcweir } ~ScJumpMatrix()98cdf0e10cSrcweir ~ScJumpMatrix() 99cdf0e10cSrcweir { 100cdf0e10cSrcweir if ( pParams ) 101cdf0e10cSrcweir { 102cdf0e10cSrcweir for ( ScTokenVec::iterator i = 103cdf0e10cSrcweir pParams->begin(); i != 104cdf0e10cSrcweir pParams->end(); ++i ) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir (*i)->DecRef(); 107cdf0e10cSrcweir } 108cdf0e10cSrcweir delete pParams; 109cdf0e10cSrcweir } 110cdf0e10cSrcweir delete [] pJump; 111cdf0e10cSrcweir } GetDimensions(SCSIZE & rCols,SCSIZE & rRows) const112cdf0e10cSrcweir void GetDimensions( SCSIZE& rCols, SCSIZE& rRows ) const 113cdf0e10cSrcweir { 114cdf0e10cSrcweir rCols = nCols; 115cdf0e10cSrcweir rRows = nRows; 116cdf0e10cSrcweir } SetJump(SCSIZE nCol,SCSIZE nRow,double fBool,short nStart,short nNext,short nStop=SHRT_MAX)117cdf0e10cSrcweir void SetJump( SCSIZE nCol, SCSIZE nRow, double fBool, 118cdf0e10cSrcweir short nStart, short nNext, 119cdf0e10cSrcweir short nStop = SHRT_MAX ) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir pJump[ (sal_uLong)nCol * nRows + nRow ]. 122cdf0e10cSrcweir SetJump( fBool, nStart, nNext, nStop); 123cdf0e10cSrcweir } GetJump(SCSIZE nCol,SCSIZE nRow,double & rBool,short & rStart,short & rNext,short & rStop) const124cdf0e10cSrcweir void GetJump( SCSIZE nCol, SCSIZE nRow, double& rBool, 125cdf0e10cSrcweir short& rStart, short& rNext, 126cdf0e10cSrcweir short& rStop ) const 127cdf0e10cSrcweir { 128cdf0e10cSrcweir if (nCols == 1 && nRows == 1) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir nCol = 0; 131cdf0e10cSrcweir nRow = 0; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir else if (nCols == 1 && nRow < nRows) 134cdf0e10cSrcweir nCol = 0; 135cdf0e10cSrcweir else if (nRows == 1 && nCol < nCols) 136cdf0e10cSrcweir nRow = 0; 137cdf0e10cSrcweir else if (nCols <= nCol || nRows <= nRow) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir DBG_ERROR("ScJumpMatrix::GetJump: dimension error"); 140cdf0e10cSrcweir nCol = 0; 141cdf0e10cSrcweir nRow = 0; 142cdf0e10cSrcweir } 143cdf0e10cSrcweir pJump[ (sal_uLong)nCol * nRows + nRow ]. 144cdf0e10cSrcweir GetJump( rBool, rStart, rNext, rStop); 145cdf0e10cSrcweir } SetAllJumps(double fBool,short nStart,short nNext,short nStop=SHRT_MAX)146cdf0e10cSrcweir void SetAllJumps( double fBool, 147cdf0e10cSrcweir short nStart, short nNext, 148cdf0e10cSrcweir short nStop = SHRT_MAX ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir sal_uLong n = (sal_uLong)nCols * nRows; 151cdf0e10cSrcweir for ( sal_uLong j=0; j<n; ++j ) 152cdf0e10cSrcweir { 153cdf0e10cSrcweir pJump[ j ].SetJump( fBool, nStart, 154cdf0e10cSrcweir nNext, nStop); 155cdf0e10cSrcweir } 156cdf0e10cSrcweir } SetJumpParameters(ScTokenVec * p)157cdf0e10cSrcweir void SetJumpParameters( ScTokenVec* p ) 158cdf0e10cSrcweir { pParams = p; } GetJumpParameters() const159cdf0e10cSrcweir const ScTokenVec* GetJumpParameters() const { return pParams; } GetResultMatrix() const160cdf0e10cSrcweir ScMatrix* GetResultMatrix() const { return pMat; } GetPos(SCSIZE & rCol,SCSIZE & rRow) const161cdf0e10cSrcweir void GetPos( SCSIZE& rCol, SCSIZE& rRow ) const 162cdf0e10cSrcweir { 163cdf0e10cSrcweir rCol = nCurCol; 164cdf0e10cSrcweir rRow = nCurRow; 165cdf0e10cSrcweir } Next(SCSIZE & rCol,SCSIZE & rRow)166cdf0e10cSrcweir bool Next( SCSIZE& rCol, SCSIZE& rRow ) 167cdf0e10cSrcweir { 168cdf0e10cSrcweir if ( !bStarted ) 169cdf0e10cSrcweir { 170cdf0e10cSrcweir bStarted = true; 171cdf0e10cSrcweir nCurCol = nCurRow = 0; 172cdf0e10cSrcweir } 173cdf0e10cSrcweir else 174cdf0e10cSrcweir { 175cdf0e10cSrcweir if ( ++nCurRow >= nResMatRows ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir nCurRow = 0; 178cdf0e10cSrcweir ++nCurCol; 179cdf0e10cSrcweir } 180cdf0e10cSrcweir } 181cdf0e10cSrcweir GetPos( rCol, rRow ); 182cdf0e10cSrcweir return nCurCol < nResMatCols; 183cdf0e10cSrcweir } GetResMatDimensions(SCSIZE & rCols,SCSIZE & rRows)184cdf0e10cSrcweir void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows ) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir rCols = nResMatCols; 187cdf0e10cSrcweir rRows = nResMatRows; 188cdf0e10cSrcweir } SetNewResMat(SCSIZE nNewCols,SCSIZE nNewRows)189cdf0e10cSrcweir void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir if ( nNewCols > nResMatCols || nNewRows > nResMatRows ) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir pMat = pMat->CloneAndExtend( nNewCols, nNewRows ); 194cdf0e10cSrcweir if ( nResMatCols < nNewCols ) 195cdf0e10cSrcweir { 196cdf0e10cSrcweir pMat->FillDouble( CreateDoubleError( 197cdf0e10cSrcweir NOTAVAILABLE), nResMatCols, 0, nNewCols-1, 198cdf0e10cSrcweir nResMatRows-1); 199cdf0e10cSrcweir } 200cdf0e10cSrcweir if ( nResMatRows < nNewRows ) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir pMat->FillDouble( CreateDoubleError( 203cdf0e10cSrcweir NOTAVAILABLE), 0, nResMatRows, nNewCols-1, 204cdf0e10cSrcweir nNewRows-1); 205cdf0e10cSrcweir } 206cdf0e10cSrcweir if ( nRows == 1 && nCurCol != 0 ) 207cdf0e10cSrcweir { 208cdf0e10cSrcweir nCurCol = 0; 209cdf0e10cSrcweir nCurRow = nResMatRows - 1; 210cdf0e10cSrcweir } 211cdf0e10cSrcweir nResMatCols = nNewCols; 212cdf0e10cSrcweir nResMatRows = nNewRows; 213cdf0e10cSrcweir } 214cdf0e10cSrcweir } 215cdf0e10cSrcweir }; 216cdf0e10cSrcweir 217cdf0e10cSrcweir #endif // SC_JUMPMATRIX_HXX 218cdf0e10cSrcweir 219