HPCToolkit
IteratorStack.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 // IteratorStack.C
49 //
50 // an iterator that is realized as a stack of iterators. this abstraction
51 // is useful for traversing nested structures.
52 //
53 // Author: John Mellor-Crummey
54 //
55 // Creation Date: October 1993
56 //
57 // Modification History:
58 // see IteratorStack.h
59 //
60 //***************************************************************************
61 
62 //************************** System Include Files ***************************
63 
64 //*************************** User Include Files ****************************
65 
66 #include "IteratorStack.hpp"
67 #include "PointerStack.hpp"
68 #include "diagnostics.h"
69 
70 //*************************** Forward Declarations **************************
71 
72 //***************************************************************************
73 
76 };
77 
78 
80  IterStackEnumType _enumType)
81 {
82  iteratorStackRepr = new IteratorStackS;
83  InitTraversal(torder, _enumType);
84 }
85 
86 
88 {
89  FreeStack(0);
90  delete iteratorStackRepr;
91 }
92 
94 {
95  return (StackableIterator*) iteratorStackRepr->pstack.Top();
96 }
97 
99 {
100  return (StackableIterator*) iteratorStackRepr->pstack.Get(depth);
101 }
102 
103 
105 {
106  while (newtop != 0) {
107  if (newtop->CurrentUpCall() == 0) {
108  // don't really push empty iterators
109  delete newtop;
110  break;
111  }
112  iteratorStackRepr->pstack.Push(newtop);
113  if (traversalOrder != PostOrder) break;
114  newtop = IteratorToPushIfAny(newtop->CurrentUpCall());
115  }
116 }
117 
118 
120 {
121  (*this)++;
122 }
123 
124 
126 {
127  for(;;) {
128  StackableIterator* top = Top();
129  if (top == 0) break;
130 
131  if ((traversalOrder == PreOrder) || (traversalOrder == PreAndPostOrder)) {
132  void* current = top->CurrentUpCall();
133  (*top)++; // advance iterator at the top of stack
134  if (current) {
135  Push(IteratorToPushIfAny(current));
136  top = Top();
137  }
138  }
139  else
140  (*top)++; // advance iterator at the top of stack
141 
142  if (top->IsValid() == false) {
143  bool popped = false;
144  while ((Top()->IsValid() == false) &&
145  (iteratorStackRepr->pstack.Depth() > 1)) {
146  FreeTop();
147  popped = true;
148  }
149  if (popped && (enumType == ITER_STACK_ENUM_LEAVES_ONLY))
150  continue;
151  } else if (traversalOrder == PostOrder) {
152  void* current = top->CurrentUpCall();
153  if (current) {
154  Push(IteratorToPushIfAny(current));
155  }
156  }
157  break;
158  }
159 }
160 
161 
163  IterStackEnumType _enumType)
164 {
165  InitTraversal(torder, _enumType);
166  FreeStack(0);
167 }
168 
169 
171 {
172  FreeStack(1); // leave at most the top element on stack
173  StackableIterator* top = Top();
174  if (top) {
175  top->Reset();
176  if (traversalOrder == PostOrder)
177  Push(IteratorToPushIfAny(top->CurrentUpCall()));
178  }
179 }
180 
182 {
183  InitTraversal(torder, _enumType);
184  Reset();
185 }
186 
187 
189 {
190  StackableIterator* top = Top();
191  return (top ? top->CurrentUpCall() : 0);
192 }
193 
194 
196 {
197  StackableIterator* top = Top();
198  return (top ? top->IsValid() : false);
199 }
200 
202 {
203  switch(clientTraversalOrder) {
204  case PreOrder:
205  case ReversePreOrder:
206  return PreVisit;
207  case PostOrder:
208  case ReversePostOrder:
209  return PostVisit;
210 //case ReversePreAndPostOrder:
211  case PreAndPostOrder: {
212  StackableIterator* top = dynamic_cast<StackableIterator*>(Top());
213  SingletonIterator* stop = dynamic_cast<SingletonIterator*>(top);
214  if (top == 0) {
215  DIAG_Die("");
216  } else if (stop != 0) {
217  return stop->VisitType();
218  } else {
219  return PreVisit;
220  }
221  }
222  default:
223  DIAG_Die("");
224  }
225  return PostVisit; // bogus return--not reached
226 }
227 
229 {
230  return clientTraversalOrder;
231 }
232 
234 {
235  switch(clientTraversalOrder) {
236  case PreOrder:
237  case PostOrder:
238  case PreAndPostOrder:
239  return true;
240  case ReversePreOrder:
241  case ReversePostOrder:
242 //case ReversePreAndPostOrder:
243  return false;
244  default:
245  DIAG_Die("");
246  }
247  return false; // bogus return--not reached
248 }
249 
251 {
252  return iteratorStackRepr->pstack.Depth();
253 }
254 
255 
257 {
258  StackableIterator* top= (StackableIterator*) iteratorStackRepr->pstack.Pop();
259  if (top)
260  delete top;
261 }
262 
263 
264 // free the top (depth - maxDepth) elements on the stack, leaving at
265 // most maxDepth elements on the stack: FreeStack(1) leaves at most one
266 // element on the stack
267 void IteratorStack::FreeStack(int maxDepth)
268 {
269  int depth = iteratorStackRepr->pstack.Depth();
270  while (depth-- > maxDepth)
271  FreeTop();
272 }
273 
274 
276  IterStackEnumType _enumType)
277 {
278  clientTraversalOrder = torder;
279  enumType = _enumType;
280  if (enumType == ITER_STACK_ENUM_LEAVES_ONLY)
281  traversalOrder = PostOrder;
282  else if (torder == ReversePreOrder)
283  traversalOrder = PreOrder; // reversed by IteratorToPushIfAny
284  else if (torder == ReversePostOrder)
285  traversalOrder = PostOrder; // reversed by IteratorToPushIfAny
286 //else if (torder == ReversePreAndPostOrder)
287 // traversalOrder = PreAndPostOrder; // reversed by IteratorToPushIfAny
288  else {
289  DIAG_Assert((torder == PreOrder) || (torder == PostOrder) ||
290  (torder == PreAndPostOrder), "");
291  traversalOrder = torder;
292  }
293 }
294 
295 
297 {
298  //dumpHandler.BeginScope();
299  int depth = iteratorStackRepr->pstack.Depth();
300  for (; --depth >= 0; ) {
301  StackableIterator* it =
302  (StackableIterator*) iteratorStackRepr->pstack.Get(depth);
303  it->Dump();
304  }
305  //dumpHandler.EndScope();
306 }
307 
308 
309 
310 //****************************************************************************
311 // class SingletonIterator
312 //****************************************************************************
313 
314 SingletonIterator::SingletonIterator(const void* singletonValue,
315  TraversalVisitType vtype)
316  : value(singletonValue), done(false), visitType(vtype)
317 {
318 }
319 
320 
322 {
323 }
324 
325 
327 {
328  const void* retval = done ? 0 : value;
329  return (void*) retval; // const cast away
330 }
331 
332 
334 {
335  done = true;
336 }
337 
338 
340 {
341  done = true;
342 }
343 
344 
346 {
347  done = false;
348 }
349 
350 
352 {
353  return visitType;
354 }
355 
356 
357 
358 
359 
void ReConstruct(TraversalOrder torder, IterStackEnumType enumType=ITER_STACK_ENUM_ALL_NODES)
IterStackEnumType
StackableIterator * Top(void) const
virtual bool IterationIsForward() const
PointerStack pstack
virtual void * CurrentUpCall() const =0
TraversalVisitType
TraversalVisitType VisitType() const
void FreeStack(int maxDepth)
IteratorStack(TraversalOrder torder, IterStackEnumType enumType=ITER_STACK_ENUM_ALL_NODES)
virtual void Reset()=0
TraversalOrder GetTraversalOrder() const
const void * value
SingletonIterator(const void *singletonValue, TraversalVisitType vtype)
void InitTraversal(TraversalOrder torder, IterStackEnumType enumType)
void * CurrentUpCall() const
virtual bool IsValid() const
bool IsValid() const
StackableIterator * GetIteratorAtPosition(unsigned int depth) const
virtual TraversalVisitType VisitType() const
void Push(StackableIterator *)
#define DIAG_Die(...)
Definition: diagnostics.h:267
TraversalVisitType visitType
int Depth() const
void * CurrentUpCall() const