CLHEP/Matrix/Pile.h

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 */

Class Library for High Energy Physics (version 1.8)