COPASI API  4.16.103
CMathDependencyNodeIterator.cpp
Go to the documentation of this file.
1 // Copyright (C) 2012 - 2013 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 #include "copasi.h"
7 
9 #include "CMathDependencyNode.h"
10 #include "CMathObject.h"
11 
13  mpNode(NULL),
14  mType(Dependents),
15  mItChild(),
16  mEndChild(),
17  mpParent(NULL)
18 {}
19 
21  mpNode(src.mpNode),
22  mType(src.mType),
23  mItChild(src.mItChild),
24  mEndChild(src.mEndChild),
25  mpParent(src.mpParent)
26 {}
27 
30  const CMathDependencyNode * pParent):
31  mpNode(pNode),
32  mType(type),
33  mItChild(),
34  mEndChild(),
35  mpParent(pParent)
36 {
37  if (pNode != NULL)
38  {
39  switch (mType)
40  {
41  case Dependents:
42  mItChild = mpNode->getDependents().begin();
43  mEndChild = mpNode->getDependents().end();
44  break;
45 
46  case Prerequisites:
47  mItChild = mpNode->getPrerequisites().begin();
49  break;
50  }
51  }
52 }
53 
55 {}
56 
58  mStack(),
59  mVisited(),
63 {}
64 
66  mStack(src.mStack),
67  mVisited(src.mVisited),
68  mType(src.mType),
69  mCurrentState(src.mCurrentState),
70  mProcessingModes(src.mProcessingModes)
71 {}
72 
75  mStack(),
76  mVisited(),
77  mType(type),
78  mCurrentState(Start),
79  mProcessingModes(After | End | Recursive)
80 {
81  mStack.push(CStackElement(pNode, mType, NULL));
82  mVisited.insert(pNode);
83 }
84 
86 {}
87 
89 {
90  // We must not further process any recursive
91  if (mCurrentState == Recursive)
92  {
93  mStack.pop();
94  }
95 
96  if (mStack.empty())
97  {
99 
100  return;
101  }
102 
103  CStackElement & Current = mStack.top();
104 
105  if (mCurrentState != After)
106  {
107  if (Current.mItChild != Current.mEndChild)
108  {
109  CMathDependencyNode * pNode = *Current.mItChild;
110 
111  mStack.push(CStackElement(*Current.mItChild, Current.mType, Current.mpNode));
112 
113  // This will process any children since the iterator is context unaware.
114  // It is therefore expected that we encounter recursive dependencies for
115  // intensive/extensive value pairs.
116  Current.mItChild++;
117 
118  if (mVisited.find(pNode) != mVisited.end())
119  {
120  // Indicate that this node is already in the stack and processing would lead to an
121  // infinite recursion.
123  }
124  else
125  {
126  mVisited.insert(pNode);
128  }
129 
130  return;
131  }
132 
133  if (Current.mItChild == Current.mEndChild)
134  {
136 
137  return;
138  }
139  }
140 
141  mVisited.erase(Current.mpNode);
142  mStack.pop();
143 
144  if (mStack.empty())
145  {
146  mCurrentState = End;
147 
148  return;
149  }
150 
151  CStackElement & Parent = mStack.top();
152 
153  if (Parent.mItChild != Parent.mEndChild)
154  {
156  }
157  else
158  {
160  }
161 
162  return;
163 }
164 
166 {
167  if (mCurrentState != Start)
168  {
169  increment();
170  }
171  else
172  {
174  }
175 
176  while (!(mProcessingModes & mCurrentState))
177  {
178  increment();
179  }
180 
181  return mCurrentState & ~End;
182 }
183 
185 {
186  CStackElement & Current = mStack.top();
187  Current.mItChild = Current.mEndChild;
189 
190  return mCurrentState;
191 }
192 
194 {
195  return mStack.top().mpNode;
196 }
197 
199 {
200  return mStack.top().mpNode;
201 }
202 
204 {
205  return mStack.top().mpParent;
206 }
207 
209 {
210  return mCurrentState;
211 }
212 
214 {
215  return mStack.size();
216 }
217 
219 {
220  mProcessingModes = (processingModes | End | Recursive);
221 }
222 
224 {
225  return (mProcessingModes & ~(End | Recursive));
226 }
std::vector< CMathDependencyNode * > & getPrerequisites()
std::vector< CMathDependencyNode * >::iterator mEndChild
CEvaluationNode * mpNode
std::stack< CStackElement > mStack
std::vector< CMathDependencyNode * >::iterator mItChild
const CMathDependencyNode * parent()
std::vector< CMathDependencyNode * > & getDependents()
void setProcessingModes(const Flag &processingModes)
std::set< const CMathDependencyNode * > mVisited