Version 7.5.1.1, tag libreoffice-7.5.1.1
[LibreOffice.git] / sc / inc / recursionhelper.hxx
blob6c4850905824d1841d3e4412bf506436e1ff08e0
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 #pragma once
22 #include "formularesult.hxx"
24 #include <list>
25 #include <vector>
26 #include <stack>
27 #include <o3tl/sorted_vector.hxx>
29 class ScFormulaCell;
31 struct ScFormulaRecursionEntry
33 ScFormulaCell* pCell;
34 bool bOldRunning;
35 ScFormulaResult aPreviousResult;
36 ScFormulaRecursionEntry(
37 ScFormulaCell* p, bool bR, const ScFormulaResult & rRes ) :
38 pCell(p), bOldRunning(bR), aPreviousResult( rRes)
43 typedef ::std::list< ScFormulaRecursionEntry > ScFormulaRecursionList;
45 class ScRecursionHelper
47 typedef ::std::stack< ScFormulaCell* > ScRecursionInIterationStack;
48 ScFormulaRecursionList aRecursionFormulas;
49 ScFormulaRecursionList::iterator aInsertPos;
50 ScFormulaRecursionList::iterator aLastIterationStart;
51 ScRecursionInIterationStack aRecursionInIterationStack;
52 std::vector< ScFormulaCell* > aFGList;
53 // Flag list corresponding to aFGList to indicate whether each formula-group
54 // is in a dependency evaluation mode or not.
55 std::vector< bool > aInDependencyEvalMode;
56 sal_uInt16 nRecursionCount;
57 sal_uInt16 nIteration;
58 // Count of ScFormulaCell::CheckComputeDependencies in current call-stack.
59 sal_uInt16 nDependencyComputationLevel;
60 bool bInRecursionReturn;
61 bool bDoingRecursion;
62 bool bInIterationReturn;
63 bool bConverging;
64 bool bGroupsIndependent;
65 bool bAbortingDependencyComputation;
66 std::vector< ScFormulaCell* > aTemporaryGroupCells;
67 o3tl::sorted_vector< ScFormulaCellGroup* >* pFGSet;
69 void Init();
70 void ResetIteration();
72 public:
74 ScRecursionHelper();
75 sal_uInt16 GetRecursionCount() const { return nRecursionCount; }
76 void IncRecursionCount() { ++nRecursionCount; }
77 void DecRecursionCount() { --nRecursionCount; }
78 sal_uInt16 GetDepComputeLevel() const { return nDependencyComputationLevel; }
79 void IncDepComputeLevel();
80 void DecDepComputeLevel();
81 /// A pure recursion return, no iteration.
82 bool IsInRecursionReturn() const { return bInRecursionReturn &&
83 !bInIterationReturn; }
84 void SetInRecursionReturn( bool b );
85 bool IsDoingRecursion() const { return bDoingRecursion; }
86 void SetDoingRecursion( bool b ) { bDoingRecursion = b; }
88 void Insert( ScFormulaCell* p, bool bOldRunning, const ScFormulaResult & rRes );
90 bool IsInIterationReturn() const { return bInIterationReturn; }
91 void SetInIterationReturn( bool b );
92 bool IsDoingIteration() const { return nIteration > 0; }
93 sal_uInt16 GetIteration() const { return nIteration; }
94 bool & GetConvergingReference() { return bConverging; }
95 void StartIteration();
96 void ResumeIteration();
97 void IncIteration();
98 void EndIteration();
100 const ScFormulaRecursionList::iterator& GetLastIterationStart() const { return aLastIterationStart; }
101 ScFormulaRecursionList::iterator GetIterationStart();
102 ScFormulaRecursionList::iterator GetIterationEnd();
103 /** Any return, recursion or iteration, iteration is always coupled with
104 recursion. */
105 bool IsInReturn() const { return bInRecursionReturn; }
106 const ScFormulaRecursionList& GetList() const { return aRecursionFormulas; }
107 ScFormulaRecursionList& GetList() { return aRecursionFormulas; }
108 ScRecursionInIterationStack& GetRecursionInIterationStack() { return aRecursionInIterationStack; }
110 void Clear();
112 /** Detects a simple cycle involving formula-groups and singleton formula-cells. */
113 bool PushFormulaGroup(ScFormulaCell* pCell);
114 void PopFormulaGroup();
115 bool AnyCycleMemberInDependencyEvalMode(const ScFormulaCell* pCell);
116 bool AnyParentFGInCycle();
117 void SetFormulaGroupDepEvalMode(bool bSet);
118 // When dependency computation detects a cycle, it may not compute proper cell values.
119 // This sets a flag that ScFormulaCell will use to avoid setting those new values
120 // and resetting the dirty flag, until the dependency computation bails out.
121 void AbortDependencyComputation();
122 bool IsAbortingDependencyComputation() const { return bAbortingDependencyComputation; }
124 void AddTemporaryGroupCell(ScFormulaCell* cell);
125 void CleanTemporaryGroupCells();
127 void SetFormulaGroupSet(o3tl::sorted_vector<ScFormulaCellGroup*>* pSet) { pFGSet = pSet; }
128 bool HasFormulaGroupSet() const { return pFGSet != nullptr; }
129 bool CheckFGIndependence(ScFormulaCellGroup* pFG);
130 void SetGroupsIndependent(bool bSet) { bGroupsIndependent = bSet; }
131 bool AreGroupsIndependent() { return bGroupsIndependent; }
134 /** A class to wrap ScRecursionHelper::PushFormulaGroup(),
135 ScRecursionHelper::PopFormulaGroup() and make these calls
136 exception safe. */
137 class ScFormulaGroupCycleCheckGuard
139 ScRecursionHelper& mrRecHelper;
140 bool mbShouldPop;
141 public:
142 ScFormulaGroupCycleCheckGuard() = delete;
143 ScFormulaGroupCycleCheckGuard(ScRecursionHelper& rRecursionHelper, ScFormulaCell* pCell);
144 ~ScFormulaGroupCycleCheckGuard();
148 class ScFormulaGroupDependencyComputeGuard
150 ScRecursionHelper& mrRecHelper;
151 public:
152 ScFormulaGroupDependencyComputeGuard() = delete;
153 ScFormulaGroupDependencyComputeGuard(ScRecursionHelper& rRecursionHelper);
154 ~ScFormulaGroupDependencyComputeGuard();
157 class ScCheckIndependentFGGuard
159 ScRecursionHelper& mrRecHelper;
160 bool mbUsedFGSet;
161 public:
162 ScCheckIndependentFGGuard() = delete;
163 ScCheckIndependentFGGuard(ScRecursionHelper& rRecursionHelper,
164 o3tl::sorted_vector<ScFormulaCellGroup*>* pSet);
165 ~ScCheckIndependentFGGuard();
167 bool AreGroupsIndependent();
170 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */