PtrStack.h 5.12 KB
Newer Older
1 2
/***************************************************************************
 *   Copyright (C) 2004 by Olivier Stezowski                               *
3
 *   stezow(AT)ipnl.in2p3.fr                                               *
4 5 6 7 8 9 10 11 12 13 14 15
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
16
 *   along with this program; if not, write to the                         *
17 18 19 20 21 22 23 24 25 26
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 
/** @file PtrStack.h template header file  */

#ifndef ADF_PtrStack
#define ADF_PtrStack
#define ADF_PTRSTACK_H ADF_PtrStack

27
#include <memory.h>
28

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
namespace ADF
{ 
//! PtrStack
/*!
    Because of some problems using std containers with pointer (with memory management)
    this "light" class is to be used as a stack of pointers.
    
    new objects (pointers) are added via the Add method. Once added, an individual 
    pointer cannot be removed ... but all the stack can be cleared using the Clear method.
    The Delete method makes a similar job but also delete the pointers if this is 
    set to owner via the SetOwner method.
    
    \warning Don't store pointers on array of objects in this since the delete method
    called is without [] (delete intead of delete []).
    
    MaxSize: \n
    	Max size (allocated) of the stack. 
	This is not a problem since any call of Add will expand the stack if required.
    
    FilledSize: \n
	To get the position of the last non-null pointer
	
    CurrentSize: \n
    	 Current position in the stack. 
	 The At methods allows to get one by one the pointer stored in the stack.
	 (At(GetSize()) checks then is the next pointer exist or not).  
    
    TO BE USED only with S as UShort_t or UInt_t.
*/   
template <typename T, typename S = UInt_t>
class PtrStack
{
public:
//    const S fDefaultCapacity = 16;
    
private:
65
// public:
66 67 68 69 70 71 72 73 74 75 76 77 78 79
	T **fStack;
	
	S fCurrentSize;  
	S fFilledSize;      
	S fMaxSize;   
	
	Bool_t fIsOwner; 
    
protected:
	void Init();
	void Expand(S);
	
public:
	PtrStack(S max_size = 16): 
80
		fStack(0x0), fCurrentSize(0), fFilledSize(0), fMaxSize(max_size), fIsOwner(true) { Init(); }
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
	~PtrStack();
	
	//! The object at position c is now on the top of the stack
	void SetBottom() 
		{ fCurrentSize = 0; } 
	
	void SetOwner(Bool_t own = false) 
		{ fIsOwner = own; }
	
	T *At(S which) const
		{ if ( which < fMaxSize ) return fStack[which]; return NULL; }
	
	//! Add a new pointer on the stack
	/*!
		The current poistion becomes the top position on the stack
	*/        
	void Add(T *t) 
	{ 
		if ( fFilledSize == fMaxSize ) 
			Expand(fMaxSize+10); 
		if ( fFilledSize < fMaxSize ) { fStack[fFilledSize++] = t; fCurrentSize = fFilledSize; }
	}
		
	//     void Reserve(S size) { if ( size <= fMaxSize ) return;  }
		
	//! to get the current position in the stack
	/*!
	
	*/        
	S GetSize() const 
		{ return fCurrentSize; }
	
	//!
	/*!
		remove pointers from the stack without calling delete
	*/    
	void Clear() 
	{ 
		if ( fStack == NULL || fFilledSize == 0 ) return; 	
		for (S i = 0; i < fFilledSize; i++) 
			fStack[i] = NULL ; 
		fFilledSize = fCurrentSize = 0; 
	}
		
	//!
	/*!
		remove pointers from the stack and delete it if this stack owns their objects
	*/        
	void Delete();
};
template <typename T, typename S> void PtrStack<T,S>::Init()
{
	if ( fMaxSize <= 0 ) fMaxSize = 1;
	
	if ( fStack ) 
		{ delete [] fStack; fStack = NULL; } 
	
	fStack = new T*[fMaxSize]; ::memset(fStack,0,fMaxSize*sizeof(T*)); fFilledSize = 0; fCurrentSize = 0;
}
template <typename T, typename S> void PtrStack<T,S>::Expand(S new_size)
{
	if ( new_size <= fMaxSize  ) return;
	T **tmp = new T*[new_size]; ::memset(tmp,0,new_size*sizeof(T*)); 
	
	for (S i = 0; i < fFilledSize; i++) tmp[i] = At(i);
	if ( fStack ) 
		{ delete [] fStack; fStack = NULL; } 
		
	fStack = tmp; fMaxSize = new_size;
}
template <typename T, typename S> PtrStack<T,S>::~PtrStack() 
{
	if ( fStack ) { Delete(); delete [] fStack; }
}
template <typename T, typename S> void PtrStack<T,S>::Delete() 
{

	if ( fStack == NULL || fFilledSize == 0 ) return; 
	
	for (S i = 0; i < fMaxSize; i++) {	
Jérémie Dudouet's avatar
Jérémie Dudouet committed
161 162
        if ( fStack[i] && fIsOwner ) delete fStack[i];
        fStack[i] = NULL;
163 164 165 166 167 168 169 170 171 172
	}
	fFilledSize = fCurrentSize = 0; 
}
}
#endif