1 /*
2  * PROPRIETARY INFORMATION.  This software is proprietary to POWDER
3  * Development, and is not to be reproduced, transmitted, or disclosed
4  * in any way without written permission.
5  *
6  * Produced by:	Jeff Lait
7  *
8  *      	POWDER Development
9  *
10  * NAME:        itemstack.cpp ( POWDER Library, C++ )
11  *
12  * COMMENTS:
13  * 	Implementation of the itemstack functions
14  */
15 
16 #include <string.h>
17 #include "assert.h"
18 #include "itemstack.h"
19 
20 template <typename PTR>
PTRSTACK()21 PTRSTACK<PTR>::PTRSTACK()
22 {
23     myEntries = 0;
24     myExtraSize = 0;
25     myExtraList = 0;
26 }
27 
28 template <typename PTR>
~PTRSTACK()29 PTRSTACK<PTR>::~PTRSTACK()
30 {
31     delete [] myExtraList;
32 }
33 
34 template <typename PTR>
35 void
append(PTR item)36 PTRSTACK<PTR>::append(PTR item)
37 {
38     if (myEntries >= PTRSTACK_MINSIZE)
39     {
40 	// Need to add to the extra stack.
41 	if (myEntries >= PTRSTACK_MINSIZE + myExtraSize)
42 	{
43 	    // Need to expand the extra stack.
44 	    PTR		*newlist;
45 
46 	    myExtraSize = myExtraSize * 2 + PTRSTACK_MINSIZE;
47 	    newlist = new PTR[myExtraSize];
48 	    if (myExtraList)
49 		memcpy(newlist, myExtraList,
50 			sizeof(PTR) * (myEntries - PTRSTACK_MINSIZE));
51 	    delete [] myExtraList;
52 	    myExtraList = newlist;
53 	}
54 	myExtraList[myEntries - PTRSTACK_MINSIZE] = item;
55     }
56     else
57 	myLocal[myEntries] = item;
58 
59     myEntries++;
60 }
61 
62 template <typename PTR>
63 void
set(int idx,PTR item)64 PTRSTACK<PTR>::set(int idx, PTR item)
65 {
66     UT_ASSERT(idx < entries());
67     UT_ASSERT(idx >= 0);
68     if (idx < 0)
69 	return;
70     if (idx >= entries())
71 	return;
72 
73     if (idx >= PTRSTACK_MINSIZE)
74     {
75 	idx -= PTRSTACK_MINSIZE;
76 	myExtraList[idx] = item;
77     }
78     else
79 	myLocal[idx] = item;
80 }
81 
82 template <typename PTR>
83 void
setEntries(int entries)84 PTRSTACK<PTR>::setEntries(int entries)
85 {
86     UT_ASSERT(entries <= myEntries);
87     if (entries > myEntries)
88 	return;
89 
90     myEntries = entries;
91 }
92 
93 template <typename PTR>
94 PTR
operator ()(int idx) const95 PTRSTACK<PTR>::operator()(int idx) const
96 {
97     UT_ASSERT(idx >= 0 && idx < myEntries);
98     if (idx < 0 || idx >= myEntries)
99     {
100 	// This is so you only have to implement an int constructor.
101 	return 0;
102     }
103 
104     if (idx < PTRSTACK_MINSIZE)
105 	return myLocal[idx];
106 
107     idx -= PTRSTACK_MINSIZE;
108     return myExtraList[idx];
109 }
110 
111 
112 template <typename PTR>
113 int
entries() const114 PTRSTACK<PTR>::entries() const
115 {
116     return myEntries;
117 }
118 
119 template <typename PTR>
120 void
clear()121 PTRSTACK<PTR>::clear()
122 {
123     setEntries(0);
124 }
125 
126 template <typename PTR>
127 void
collapse()128 PTRSTACK<PTR>::collapse()
129 {
130     int		i, j;
131 
132     for (i = 0, j = 0; i < entries(); i++)
133     {
134 	if (!(*this)(i))
135 	{
136 	    // Don't increment j!
137 	}
138 	else
139 	{
140 	    if (i != j)
141 		set(j++, (*this)(i));
142 	    else
143 		j++;
144 	}
145     }
146     // Update number of entries.
147     setEntries(j);
148 }
149 
150 template <typename PTR>
151 void
reverse()152 PTRSTACK<PTR>::reverse()
153 {
154     PTR		 tmp;
155     int		 i, n, r;
156 
157     n = entries();
158     for (i = 0; i < n / 2; i++)
159     {
160 	// Reversed entry.
161 	r = n - 1 - i;
162 	tmp = (*this)(i);
163 	set(i, (*this)(r));
164 	set(r, tmp);
165     }
166 }
167