Bump version to 6.4-15
[LibreOffice.git] / sc / inc / recursionhelper.hxx
blob477eb2a4d00ed6469a23e4517ad8085d3aa76944
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SC_INC_RECURSIONHELPER_HXX
21 #define INCLUDED_SC_INC_RECURSIONHELPER_HXX
23 #include "formularesult.hxx"
25 #include <list>
26 #include <vector>
27 #include <stack>
28 #include <unordered_set>
30 class ScFormulaCell;
32 struct ScFormulaRecursionEntry
34 ScFormulaCell* const pCell;
35 bool const bOldRunning;
36 ScFormulaResult aPreviousResult;
37 ScFormulaRecursionEntry(
38 ScFormulaCell* p, bool bR, const ScFormulaResult & rRes ) :
39 pCell(p), bOldRunning(bR), aPreviousResult( rRes)
44 typedef ::std::list< ScFormulaRecursionEntry > ScFormulaRecursionList;
46 class ScRecursionHelper
48 typedef ::std::stack< ScFormulaCell* > ScRecursionInIterationStack;
49 typedef ::std::vector< ScFormulaCell* > ScFGList;
50 ScFormulaRecursionList aRecursionFormulas;
51 ScFormulaRecursionList::iterator aInsertPos;
52 ScFormulaRecursionList::iterator aLastIterationStart;
53 ScRecursionInIterationStack aRecursionInIterationStack;
54 ScFGList aFGList;
55 // Flag list corresponding to aFGList to indicate whether each formula-group
56 // is in a dependency evaluation mode or not.
57 std::vector< bool > aInDependencyEvalMode;
58 sal_uInt16 nRecursionCount;
59 sal_uInt16 nIteration;
60 // Count of ScFormulaCell::CheckComputeDependencies in current call-stack.
61 sal_uInt16 nDependencyComputationLevel;
62 bool bInRecursionReturn;
63 bool bDoingRecursion;
64 bool bInIterationReturn;
65 bool bConverging;
66 bool bGroupsIndependent;
67 bool bAbortingDependencyComputation;
68 std::vector< ScFormulaCell* > aTemporaryGroupCells;
69 std::unordered_set< ScFormulaCellGroup* >* pFGSet;
71 void Init();
72 void ResetIteration();
74 public:
76 ScRecursionHelper();
77 sal_uInt16 GetRecursionCount() const { return nRecursionCount; }
78 void IncRecursionCount() { ++nRecursionCount; }
79 void DecRecursionCount() { --nRecursionCount; }
80 sal_uInt16 GetDepComputeLevel() const { return nDependencyComputationLevel; }
81 void IncDepComputeLevel();
82 void DecDepComputeLevel();
83 /// A pure recursion return, no iteration.
84 bool IsInRecursionReturn() const { return bInRecursionReturn &&
85 !bInIterationReturn; }
86 void SetInRecursionReturn( bool b );
87 bool IsDoingRecursion() const { return bDoingRecursion; }
88 void SetDoingRecursion( bool b ) { bDoingRecursion = b; }
90 void Insert( ScFormulaCell* p, bool bOldRunning, const ScFormulaResult & rRes );
92 bool IsInIterationReturn() const { return bInIterationReturn; }
93 void SetInIterationReturn( bool b );
94 bool IsDoingIteration() const { return nIteration > 0; }
95 sal_uInt16 GetIteration() const { return nIteration; }
96 bool & GetConvergingReference() { return bConverging; }
97 void StartIteration();
98 void ResumeIteration();
99 void IncIteration();
100 void EndIteration();
102 const ScFormulaRecursionList::iterator& GetLastIterationStart() const { return aLastIterationStart; }
103 ScFormulaRecursionList::iterator GetIterationStart();
104 ScFormulaRecursionList::iterator GetIterationEnd();
105 /** Any return, recursion or iteration, iteration is always coupled with
106 recursion. */
107 bool IsInReturn() const { return bInRecursionReturn; }
108 const ScFormulaRecursionList& GetList() const { return aRecursionFormulas; }
109 ScFormulaRecursionList& GetList() { return aRecursionFormulas; }
110 ScRecursionInIterationStack& GetRecursionInIterationStack() { return aRecursionInIterationStack; }
112 void Clear();
114 /** Detects a simple cycle involving formula-groups and singleton formula-cells. */
115 bool PushFormulaGroup(ScFormulaCell* pCell);
116 void PopFormulaGroup();
117 bool AnyCycleMemberInDependencyEvalMode(ScFormulaCell* pCell);
118 bool AnyParentFGInCycle();
119 void SetFormulaGroupDepEvalMode(bool bSet);
120 // When dependency computation detects a cycle, it may not compute proper cell values.
121 // This sets a flag that ScFormulaCell will use to avoid setting those new values
122 // and resetting the dirty flag, until the dependency computation bails out.
123 void AbortDependencyComputation();
124 bool IsAbortingDependencyComputation() const { return bAbortingDependencyComputation; }
126 void AddTemporaryGroupCell(ScFormulaCell* cell);
127 void CleanTemporaryGroupCells();
129 void SetFormulaGroupSet(std::unordered_set<ScFormulaCellGroup*>* pSet) { pFGSet = pSet; }
130 bool HasFormulaGroupSet() { return pFGSet != nullptr; }
131 bool CheckFGIndependence(ScFormulaCellGroup* pFG);
132 void SetGroupsIndependent(bool bSet) { bGroupsIndependent = bSet; }
133 bool AreGroupsIndependent() { return bGroupsIndependent; }
136 /** A class to wrap ScRecursionHelper::PushFormulaGroup(),
137 ScRecursionHelper::PopFormulaGroup() and make these calls
138 exception safe. */
139 class ScFormulaGroupCycleCheckGuard
141 ScRecursionHelper& mrRecHelper;
142 bool mbShouldPop;
143 public:
144 ScFormulaGroupCycleCheckGuard() = delete;
145 ScFormulaGroupCycleCheckGuard(ScRecursionHelper& rRecursionHelper, ScFormulaCell* pCell);
146 ~ScFormulaGroupCycleCheckGuard();
150 class ScFormulaGroupDependencyComputeGuard
152 ScRecursionHelper& mrRecHelper;
153 public:
154 ScFormulaGroupDependencyComputeGuard() = delete;
155 ScFormulaGroupDependencyComputeGuard(ScRecursionHelper& rRecursionHelper);
156 ~ScFormulaGroupDependencyComputeGuard();
159 class ScCheckIndependentFGGuard
161 ScRecursionHelper& mrRecHelper;
162 bool mbUsedFGSet;
163 public:
164 ScCheckIndependentFGGuard() = delete;
165 ScCheckIndependentFGGuard(ScRecursionHelper& rRecursionHelper,
166 std::unordered_set<ScFormulaCellGroup*>* pSet);
167 ~ScCheckIndependentFGGuard();
169 bool AreGroupsIndependent();
172 #endif // INCLUDED_SC_INC_RECURSIONHELPER_HXX
174 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */