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 10*38d50f7bSAndrew Rist * 11*38d50f7bSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*38d50f7bSAndrew Rist * 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. 19*38d50f7bSAndrew Rist * 20*38d50f7bSAndrew Rist *************************************************************/ 21*38d50f7bSAndrew Rist 22*38d50f7bSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #ifndef INCLUDED_RECURSIONHELPER_HXX 25cdf0e10cSrcweir #define INCLUDED_RECURSIONHELPER_HXX 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "formularesult.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <list> 30cdf0e10cSrcweir #include <stack> 31cdf0e10cSrcweir #include <tools/solar.h> 32cdf0e10cSrcweir 33cdf0e10cSrcweir class ScFormulaCell; 34cdf0e10cSrcweir 35cdf0e10cSrcweir struct ScFormulaRecursionEntry 36cdf0e10cSrcweir { 37cdf0e10cSrcweir ScFormulaCell* pCell; 38cdf0e10cSrcweir sal_Bool bOldRunning; 39cdf0e10cSrcweir ScFormulaResult aPreviousResult; ScFormulaRecursionEntryScFormulaRecursionEntry40cdf0e10cSrcweir ScFormulaRecursionEntry( ScFormulaCell* p, sal_Bool bR, 41cdf0e10cSrcweir const ScFormulaResult & rRes ) : 42cdf0e10cSrcweir pCell(p), bOldRunning(bR), aPreviousResult( rRes) 43cdf0e10cSrcweir { 44cdf0e10cSrcweir } 45cdf0e10cSrcweir }; 46cdf0e10cSrcweir 47cdf0e10cSrcweir typedef ::std::list< ScFormulaRecursionEntry > ScFormulaRecursionList; 48cdf0e10cSrcweir 49cdf0e10cSrcweir class ScRecursionHelper 50cdf0e10cSrcweir { 51cdf0e10cSrcweir typedef ::std::stack< ScFormulaCell* > ScRecursionInIterationStack; 52cdf0e10cSrcweir ScFormulaRecursionList aRecursionFormulas; 53cdf0e10cSrcweir ScFormulaRecursionList::iterator aInsertPos; 54cdf0e10cSrcweir ScFormulaRecursionList::iterator aLastIterationStart; 55cdf0e10cSrcweir ScRecursionInIterationStack aRecursionInIterationStack; 56cdf0e10cSrcweir sal_uInt16 nRecursionCount; 57cdf0e10cSrcweir sal_uInt16 nIteration; 58cdf0e10cSrcweir bool bInRecursionReturn; 59cdf0e10cSrcweir bool bDoingRecursion; 60cdf0e10cSrcweir bool bInIterationReturn; 61cdf0e10cSrcweir bool bConverging; 62cdf0e10cSrcweir Init()63cdf0e10cSrcweir void Init() 64cdf0e10cSrcweir { 65cdf0e10cSrcweir nRecursionCount = 0; 66cdf0e10cSrcweir bInRecursionReturn = bDoingRecursion = bInIterationReturn = false; 67cdf0e10cSrcweir aInsertPos = GetEnd(); 68cdf0e10cSrcweir ResetIteration(); 69cdf0e10cSrcweir } ResetIteration()70cdf0e10cSrcweir void ResetIteration() 71cdf0e10cSrcweir { 72cdf0e10cSrcweir aLastIterationStart = GetEnd(); 73cdf0e10cSrcweir nIteration = 0; 74cdf0e10cSrcweir bConverging = false; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir 77cdf0e10cSrcweir public: 78cdf0e10cSrcweir ScRecursionHelper()79cdf0e10cSrcweir ScRecursionHelper() { Init(); } GetRecursionCount() const80cdf0e10cSrcweir sal_uInt16 GetRecursionCount() const { return nRecursionCount; } IncRecursionCount()81cdf0e10cSrcweir void IncRecursionCount() { ++nRecursionCount; } DecRecursionCount()82cdf0e10cSrcweir void DecRecursionCount() { --nRecursionCount; } 83cdf0e10cSrcweir /// A pure recursion return, no iteration. IsInRecursionReturn() const84cdf0e10cSrcweir bool IsInRecursionReturn() const { return bInRecursionReturn && 85cdf0e10cSrcweir !bInIterationReturn; } SetInRecursionReturn(bool b)86cdf0e10cSrcweir void SetInRecursionReturn( bool b ) 87cdf0e10cSrcweir { 88cdf0e10cSrcweir // Do not use IsInRecursionReturn() here, it decouples iteration. 89cdf0e10cSrcweir if (b && !bInRecursionReturn) 90cdf0e10cSrcweir aInsertPos = aRecursionFormulas.begin(); 91cdf0e10cSrcweir bInRecursionReturn = b; 92cdf0e10cSrcweir } IsDoingRecursion() const93cdf0e10cSrcweir bool IsDoingRecursion() const { return bDoingRecursion; } SetDoingRecursion(bool b)94cdf0e10cSrcweir void SetDoingRecursion( bool b ) { bDoingRecursion = b; } Insert(ScFormulaCell * p,sal_Bool bOldRunning,const ScFormulaResult & rRes)95cdf0e10cSrcweir void Insert( ScFormulaCell* p, sal_Bool bOldRunning, 96cdf0e10cSrcweir const ScFormulaResult & rRes ) 97cdf0e10cSrcweir { 98cdf0e10cSrcweir aRecursionFormulas.insert( aInsertPos, ScFormulaRecursionEntry( p, 99cdf0e10cSrcweir bOldRunning, rRes)); 100cdf0e10cSrcweir } GetStart()101cdf0e10cSrcweir ScFormulaRecursionList::iterator GetStart() 102cdf0e10cSrcweir { 103cdf0e10cSrcweir return aRecursionFormulas.begin(); 104cdf0e10cSrcweir } GetEnd()105cdf0e10cSrcweir ScFormulaRecursionList::iterator GetEnd() 106cdf0e10cSrcweir { 107cdf0e10cSrcweir return aRecursionFormulas.end(); 108cdf0e10cSrcweir } IsInIterationReturn() const109cdf0e10cSrcweir bool IsInIterationReturn() const { return bInIterationReturn; } SetInIterationReturn(bool b)110cdf0e10cSrcweir void SetInIterationReturn( bool b ) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir // An iteration return is always coupled to a recursion return. 113cdf0e10cSrcweir SetInRecursionReturn( b); 114cdf0e10cSrcweir bInIterationReturn = b; 115cdf0e10cSrcweir } IsDoingIteration() const116cdf0e10cSrcweir bool IsDoingIteration() const { return nIteration > 0; } GetIteration() const117cdf0e10cSrcweir sal_uInt16 GetIteration() const { return nIteration; } GetConvergingReference()118cdf0e10cSrcweir bool & GetConvergingReference() { return bConverging; } StartIteration()119cdf0e10cSrcweir void StartIteration() 120cdf0e10cSrcweir { 121cdf0e10cSrcweir SetInIterationReturn( false); 122cdf0e10cSrcweir nIteration = 1; 123cdf0e10cSrcweir bConverging = false; 124cdf0e10cSrcweir aLastIterationStart = GetIterationStart(); 125cdf0e10cSrcweir } ResumeIteration()126cdf0e10cSrcweir void ResumeIteration() 127cdf0e10cSrcweir { 128cdf0e10cSrcweir SetInIterationReturn( false); 129cdf0e10cSrcweir aLastIterationStart = GetIterationStart(); 130cdf0e10cSrcweir } IncIteration()131cdf0e10cSrcweir void IncIteration() { ++nIteration; } EndIteration()132cdf0e10cSrcweir void EndIteration() 133cdf0e10cSrcweir { 134cdf0e10cSrcweir aRecursionFormulas.erase( GetIterationStart(), GetIterationEnd()); 135cdf0e10cSrcweir ResetIteration(); 136cdf0e10cSrcweir } GetLastIterationStart()137cdf0e10cSrcweir ScFormulaRecursionList::iterator GetLastIterationStart() { return aLastIterationStart; } GetIterationStart()138cdf0e10cSrcweir ScFormulaRecursionList::iterator GetIterationStart() { return GetStart(); } GetIterationEnd()139cdf0e10cSrcweir ScFormulaRecursionList::iterator GetIterationEnd() { return GetEnd(); } 140cdf0e10cSrcweir /** Any return, recursion or iteration, iteration is always coupled with 141cdf0e10cSrcweir recursion. */ IsInReturn() const142cdf0e10cSrcweir bool IsInReturn() const { return bInRecursionReturn; } GetList() const143cdf0e10cSrcweir const ScFormulaRecursionList& GetList() const { return aRecursionFormulas; } GetList()144cdf0e10cSrcweir ScFormulaRecursionList& GetList() { return aRecursionFormulas; } GetRecursionInIterationStack()145cdf0e10cSrcweir ScRecursionInIterationStack& GetRecursionInIterationStack() { return aRecursionInIterationStack; } Clear()146cdf0e10cSrcweir void Clear() 147cdf0e10cSrcweir { 148cdf0e10cSrcweir aRecursionFormulas.clear(); 149cdf0e10cSrcweir while (!aRecursionInIterationStack.empty()) 150cdf0e10cSrcweir aRecursionInIterationStack.pop(); 151cdf0e10cSrcweir Init(); 152cdf0e10cSrcweir } 153cdf0e10cSrcweir }; 154cdf0e10cSrcweir 155cdf0e10cSrcweir #endif // INCLUDED_RECURSIONHELPER_HXX 156