CLHEP VERSION Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // -*- C++ -*- 00002 // CLASSDOC OFF 00003 // --------------------------------------------------------------------------- 00004 // CLASSDOC ON 00005 // 00006 // This file is a part of the CLHEP - a Class Library for High Energy Physics. 00007 // 00008 // This software written by Nobu Katayama and Mike Smyth, Cornell University. 00009 // 00010 // This file contains an attempt to make the template "pile". A pile is 00011 // a finite size LIFO stack. When a element is pushed on that increases 00012 // the stack beyond its maximum size, the oldest element is deleted from 00013 // the stack. A subroutine can be used on that oldest element first. 00014 00015 // The orginal use of this stack was to store old double arrays. When 00016 // a new array is needed, we can simply pull one off the pile. However, 00017 // we don't want to keep too many old array's around, after a while we just 00018 // want to start getting rid of them. When the pile gets too large, or 00019 // when the pile is destroyed, we want to call subroutines to get rid of 00020 // some of these arrays. 00021 00022 // Unfortunately, in version 2.2 of g++ templates don't seem to work unless 00023 // they are declared inline. So this class has ridiculously long inline 00024 // functions. Also, g++ doesn't seem to allow multiple arguements to 00025 // templates, so the size of the pile is hardwired in. To change the size, 00026 // change the value of the const int sz. 00027 00028 // A pile is easy to use. Just declare pile<X> X_pile. To add a X to the 00029 // pile, say X_pile.push(X item). To get an item from the pile, first 00030 // check that the pile is not empty, and then say item=X_pile.pop(). It 00031 // is an error to try and pop from an empty pile. To check if a pile is 00032 // empty, say X_pile.is_empty(). If this is TRUE, then the pile is empty. 00033 // Otherwise it is FALSE. The subroutine called when the stack begins to 00034 // overflow is set by X_pile.destroy(void (*function)(X)), or it can be 00035 // set in the construction pile<X> X_pile(void (*function)(X)). It is 00036 // okay to not supply a function, in that case nothing is done when an 00037 // item falls off the bottom of the pile. It is simply lost. 00038 00039 #ifndef _PILE_H 00040 #define _PILE_H 00041 00042 #include <iostream> 00043 #include "CLHEP/Matrix/defs.h" 00044 00050 namespace CLHEP { 00051 00052 template<class T> 00053 class HepPile 00054 { 00055 public: 00056 // Destructor 00057 // (defined first in templated class due to a bug in VxWorks) 00058 ~HepPile() 00059 { 00060 while(bottom != top) 00061 { 00062 #if 1 00063 destroy(stack[bottom]); 00064 #else 00065 delete [] stack[bottom]; 00066 #endif 00067 next(&bottom); 00068 } 00069 } 00070 00071 HepPile(void (*f)(T)=0): top(0), bottom(0) { destroy_fun = f;} 00072 00073 void set_destroy(void (*f)(T)) { destroy_fun = f;} 00074 void push(T item) 00075 { 00076 stack[top]=item; 00077 next(&top); 00078 if (top==bottom) 00079 { 00080 #if 1 00081 destroy(stack[bottom]); 00082 #else 00083 delete [] stack[bottom]; 00084 #endif 00085 next(&bottom); 00086 } 00087 } 00088 bool is_empty() const { return top == bottom ?true :false;} 00089 T pop() 00090 { 00091 if (is_empty()) 00092 { 00093 std::cerr << "Attempt to pop empty pile.\n--- Exiting to system." 00094 << std::endl; 00095 exit(1); 00096 } 00097 previous(&top); 00098 return stack[top]; 00099 } 00100 00101 private: 00102 enum {sz = 50}; 00103 T stack[sz+1]; 00104 int top,bottom; 00105 void (*destroy_fun)(T); 00106 void next(int *n) const {if (++(*n) >= sz+1) *n = 0;} 00107 void previous(int *n) const {if (--(*n) < 0) *n = sz;} 00108 void destroy(T t) { if (destroy_fun) (*destroy_fun)(t); } 00109 }; 00110 00111 } // namespace CLHEP 00112 00113 #ifdef ENABLE_BACKWARDS_COMPATIBILITY 00114 // backwards compatibility will be enabled ONLY in CLHEP 1.9 00115 using namespace CLHEP; 00116 #endif 00117 00118 #endif /*_PILE_H */