1/*
2 * Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
3 * This file may be used under the terms of the MIT License.
4 */
5#ifndef KERNEL_UTIL_STACK_H
6#define KERNEL_UTIL_STACK_H
7
8
9#include <stdlib.h>
10
11#include <SupportDefs.h>
12
13#include <AutoDeleter.h>
14
15
16template<class T> class Stack {
17	public:
18		Stack()
19			:
20			fArray(NULL),
21			fUsed(0),
22			fMax(0)
23		{
24		}
25
26		~Stack()
27		{
28			free(fArray);
29		}
30
31		bool IsEmpty() const
32		{
33			return fUsed == 0;
34		}
35
36		void MakeEmpty()
37		{
38			// could also free the memory
39			fUsed = 0;
40		}
41
42		status_t Push(T value)
43		{
44			if (fUsed >= fMax) {
45				fMax += 16;
46				T *newArray = (T *)realloc(fArray, fMax * sizeof(T));
47				if (newArray == NULL)
48					return B_NO_MEMORY;
49
50				fArray = newArray;
51			}
52			fArray[fUsed++] = value;
53			return B_OK;
54		}
55
56		bool Pop(T *value)
57		{
58			if (fUsed == 0)
59				return false;
60
61			*value = fArray[--fUsed];
62			return true;
63		}
64
65		T *Array()
66		{
67			return fArray;
68		}
69
70		int32 CountItems() const
71		{
72			return fUsed;
73		}
74
75	private:
76		T		*fArray;
77		int32	fUsed;
78		int32	fMax;
79};
80
81
82template<typename T> class StackDelete {
83public:
84	inline void operator()(Stack<T>* stack)
85	{
86		if (stack == NULL)
87			return;
88
89		T item;
90		while (stack->Pop(&item)) {
91			delete item;
92		}
93
94		delete stack;
95	}
96};
97
98template<typename T> class StackDeleter
99	: public BPrivate::AutoDeleter<Stack<T>, StackDelete<T> > {
100public:
101	StackDeleter()
102	{
103	}
104
105	StackDeleter(Stack<T>* stack)
106		: BPrivate::AutoDeleter<Stack<T>, StackDelete<T> >(stack)
107	{
108	}
109};
110
111#endif	/* KERNEL_UTIL_STACK_H */
112