CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

Pile.h

Go to the documentation of this file.
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 */

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7