1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
28 #include <o3tl/sorted_vector.hxx>
32 struct ScFormulaRecursionEntry
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 ScFormulaRecursionList aRecursionFormulas
;
50 ScFormulaRecursionList::iterator aInsertPos
;
51 ScFormulaRecursionList::iterator aLastIterationStart
;
52 ScRecursionInIterationStack aRecursionInIterationStack
;
53 std::vector
< ScFormulaCell
* > aFGList
;
54 // Flag list corresponding to aFGList to indicate whether each formula-group
55 // is in a dependency evaluation mode or not.
56 std::vector
< bool > aInDependencyEvalMode
;
57 sal_uInt16 nRecursionCount
;
58 sal_uInt16 nIteration
;
59 // Count of ScFormulaCell::CheckComputeDependencies in current call-stack.
60 sal_uInt16 nDependencyComputationLevel
;
61 bool bInRecursionReturn
;
63 bool bInIterationReturn
;
65 bool bGroupsIndependent
;
66 bool bAbortingDependencyComputation
;
67 std::vector
< ScFormulaCell
* > aTemporaryGroupCells
;
68 o3tl::sorted_vector
< ScFormulaCellGroup
* >* pFGSet
;
71 void ResetIteration();
76 sal_uInt16
GetRecursionCount() const { return nRecursionCount
; }
77 void IncRecursionCount() { ++nRecursionCount
; }
78 void DecRecursionCount() { --nRecursionCount
; }
79 sal_uInt16
GetDepComputeLevel() const { return nDependencyComputationLevel
; }
80 void IncDepComputeLevel();
81 void DecDepComputeLevel();
82 /// A pure recursion return, no iteration.
83 bool IsInRecursionReturn() const { return bInRecursionReturn
&&
84 !bInIterationReturn
; }
85 void SetInRecursionReturn( bool b
);
86 bool IsDoingRecursion() const { return bDoingRecursion
; }
87 void SetDoingRecursion( bool b
) { bDoingRecursion
= b
; }
89 void Insert( ScFormulaCell
* p
, bool bOldRunning
, const ScFormulaResult
& rRes
);
91 bool IsInIterationReturn() const { return bInIterationReturn
; }
92 void SetInIterationReturn( bool b
);
93 bool IsDoingIteration() const { return nIteration
> 0; }
94 sal_uInt16
GetIteration() const { return nIteration
; }
95 bool & GetConvergingReference() { return bConverging
; }
96 void StartIteration();
97 void ResumeIteration();
101 const ScFormulaRecursionList::iterator
& GetLastIterationStart() const { return aLastIterationStart
; }
102 ScFormulaRecursionList::iterator
GetIterationStart();
103 ScFormulaRecursionList::iterator
GetIterationEnd();
104 /** Any return, recursion or iteration, iteration is always coupled with
106 bool IsInReturn() const { return bInRecursionReturn
; }
107 const ScFormulaRecursionList
& GetList() const { return aRecursionFormulas
; }
108 ScFormulaRecursionList
& GetList() { return aRecursionFormulas
; }
109 ScRecursionInIterationStack
& GetRecursionInIterationStack() { return aRecursionInIterationStack
; }
113 /** Detects a simple cycle involving formula-groups and singleton formula-cells. */
114 bool PushFormulaGroup(ScFormulaCell
* pCell
);
115 void PopFormulaGroup();
116 bool AnyCycleMemberInDependencyEvalMode(const ScFormulaCell
* pCell
);
117 bool AnyParentFGInCycle();
118 void SetFormulaGroupDepEvalMode(bool bSet
);
119 // When dependency computation detects a cycle, it may not compute proper cell values.
120 // This sets a flag that ScFormulaCell will use to avoid setting those new values
121 // and resetting the dirty flag, until the dependency computation bails out.
122 void AbortDependencyComputation();
123 bool IsAbortingDependencyComputation() const { return bAbortingDependencyComputation
; }
125 void AddTemporaryGroupCell(ScFormulaCell
* cell
);
126 void CleanTemporaryGroupCells();
128 void SetFormulaGroupSet(o3tl::sorted_vector
<ScFormulaCellGroup
*>* pSet
) { pFGSet
= pSet
; }
129 bool HasFormulaGroupSet() const { return pFGSet
!= nullptr; }
130 bool CheckFGIndependence(ScFormulaCellGroup
* pFG
);
131 void SetGroupsIndependent(bool bSet
) { bGroupsIndependent
= bSet
; }
132 bool AreGroupsIndependent() { return bGroupsIndependent
; }
135 /** A class to wrap ScRecursionHelper::PushFormulaGroup(),
136 ScRecursionHelper::PopFormulaGroup() and make these calls
138 class ScFormulaGroupCycleCheckGuard
140 ScRecursionHelper
& mrRecHelper
;
143 ScFormulaGroupCycleCheckGuard() = delete;
144 ScFormulaGroupCycleCheckGuard(ScRecursionHelper
& rRecursionHelper
, ScFormulaCell
* pCell
);
145 ~ScFormulaGroupCycleCheckGuard();
149 class ScFormulaGroupDependencyComputeGuard
151 ScRecursionHelper
& mrRecHelper
;
153 ScFormulaGroupDependencyComputeGuard() = delete;
154 ScFormulaGroupDependencyComputeGuard(ScRecursionHelper
& rRecursionHelper
);
155 ~ScFormulaGroupDependencyComputeGuard();
158 class ScCheckIndependentFGGuard
160 ScRecursionHelper
& mrRecHelper
;
163 ScCheckIndependentFGGuard() = delete;
164 ScCheckIndependentFGGuard(ScRecursionHelper
& rRecursionHelper
,
165 o3tl::sorted_vector
<ScFormulaCellGroup
*>* pSet
);
166 ~ScCheckIndependentFGGuard();
168 bool AreGroupsIndependent();
171 #endif // INCLUDED_SC_INC_RECURSIONHELPER_HXX
173 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */