00001 // -*- C++ -*- 00002 // CLASSDOC OFF 00003 // $Id: Pile.h,v 1.12 2002/04/12 15:02:44 evc Exp $ 00004 // --------------------------------------------------------------------------- 00005 // CLASSDOC ON 00006 // 00007 // This file is a part of the CLHEP - a Class Library for High Energy Physics. 00008 // 00009 // 00010 // Copyright Cornell University 1993, 1996, All Rights Reserved. 00011 // 00012 // This software written by Nobu Katayama and Mike Smyth, Cornell University. 00013 // 00014 // Redistribution and use in source and binary forms, with or without 00015 // modification, are permitted provided that the following conditions 00016 // are met: 00017 // 1. Redistributions of source code must retain the above copyright 00018 // notice and author attribution, this list of conditions and the 00019 // following disclaimer. 00020 // 2. Redistributions in binary form must reproduce the above copyright 00021 // notice and author attribution, this list of conditions and the 00022 // following disclaimer in the documentation and/or other materials 00023 // provided with the distribution. 00024 // 3. Neither the name of the University nor the names of its contributors 00025 // may be used to endorse or promote products derived from this software 00026 // without specific prior written permission. 00027 // 00028 // Creation of derivative forms of this software for commercial 00029 // utilization may be subject to restriction; written permission may be 00030 // obtained from Cornell University. 00031 // 00032 // CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way 00033 // of example, but not limitation, CORNELL MAKES NO REPRESENTATIONS OR 00034 // WARRANTIES OF MERCANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT 00035 // THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, 00036 // COPYRIGHTS, TRADEMARKS, OR OTHER RIGHTS. Cornell University shall not be 00037 // held liable for any liability with respect to any claim by the user or any 00038 // other party arising from use of the program. 00039 // 00040 00041 // This file contains an attempt to make the template "pile". A pile is 00042 // a finite size LIFO stack. When a element is pushed on that increases 00043 // the stack beyond its maximum size, the oldest element is deleted from 00044 // the stack. A subroutine can be used on that oldest element first. 00045 00046 // The orginal use of this stack was to store old double arrays. When 00047 // a new array is needed, we can simply pull one off the pile. However, 00048 // we don't want to keep too many old array's around, after a while we just 00049 // want to start getting rid of them. When the pile gets too large, or 00050 // when the pile is destroyed, we want to call subroutines to get rid of 00051 // some of these arrays. 00052 00053 // Unfortunately, in version 2.2 of g++ templates don't seem to work unless 00054 // they are declared inline. So this class has ridiculously long inline 00055 // functions. Also, g++ doesn't seem to allow multiple arguements to 00056 // templates, so the size of the pile is hardwired in. To change the size, 00057 // change the value of the const int sz. 00058 00059 // A pile is easy to use. Just declare pile<X> X_pile. To add a X to the 00060 // pile, say X_pile.push(X item). To get an item from the pile, first 00061 // check that the pile is not empty, and then say item=X_pile.pop(). It 00062 // is an error to try and pop from an empty pile. To check if a pile is 00063 // empty, say X_pile.is_empty(). If this is TRUE, then the pile is empty. 00064 // Otherwise it is FALSE. The subroutine called when the stack begins to 00065 // overflow is set by X_pile.destroy(void (*function)(X)), or it can be 00066 // set in the construction pile<X> X_pile(void (*function)(X)). It is 00067 // okay to not supply a function, in that case nothing is done when an 00068 // item falls off the bottom of the pile. It is simply lost. 00069 00070 #ifndef _PILE_H 00071 #define _PILE_H 00072 00073 #include "CLHEP/config/CLHEP.h" 00074 #include "CLHEP/config/iostream.h" 00075 00080 template<class T> 00081 class HepPile 00082 { 00083 public: 00084 // Destructor 00085 // (defined first in templated class due to a bug in VxWorks) 00086 ~HepPile() 00087 { 00088 while(bottom != top) 00089 { 00090 #if 1 00091 destroy(stack[bottom]); 00092 #else 00093 delete [] stack[bottom]; 00094 #endif 00095 next(&bottom); 00096 } 00097 } 00098 00099 HepPile(void (*f)(T)=0): top(0), bottom(0) { destroy_fun = f;} 00100 00101 void set_destroy(void (*f)(T)) { destroy_fun = f;} 00102 void push(T item) 00103 { 00104 stack[top]=item; 00105 next(&top); 00106 if (top==bottom) 00107 { 00108 #if 1 00109 destroy(stack[bottom]); 00110 #else 00111 delete [] stack[bottom]; 00112 #endif 00113 next(&bottom); 00114 } 00115 } 00116 bool is_empty() const { return top == bottom ?true :false;} 00117 T pop() 00118 { 00119 if (is_empty()) 00120 { 00121 HepStd::cerr << "Attempt to pop empty pile.\n--- Exiting to system." 00122 << HepStd::endl; 00123 exit(1); 00124 } 00125 previous(&top); 00126 return stack[top]; 00127 } 00128 00129 private: 00130 enum {sz = 50}; 00131 T stack[sz+1]; 00132 int top,bottom; 00133 void (*destroy_fun)(T); 00134 void next(int *n) const {if (++(*n) >= sz+1) *n = 0;} 00135 void previous(int *n) const {if (--(*n) < 0) *n = sz;} 00136 void destroy(T t) { if (destroy_fun) (*destroy_fun)(t); } 00137 }; 00138 00139 #endif /*_PILE_H */