aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp')
-rw-r--r--libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp345
1 files changed, 345 insertions, 0 deletions
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp b/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp
new file mode 100644
index 0000000..8a4a570
--- /dev/null
+++ b/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp
@@ -0,0 +1,345 @@
1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2/**
3 * Contains a simple container class.
4 * \file IceContainer.cpp
5 * \author Pierre Terdiman
6 * \date February, 5, 2000
7 */
8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11/**
12 * Contains a list of 32-bits values.
13 * Use this class when you need to store an unknown number of values. The list is automatically
14 * resized and can contains 32-bits entities (dwords or floats)
15 *
16 * \class Container
17 * \author Pierre Terdiman
18 * \version 1.0
19 * \date 08.15.98
20*/
21///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22
23///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24// Precompiled Header
25#include "Stdafx.h"
26
27using namespace IceCore;
28
29// Static members
30#ifdef CONTAINER_STATS
31udword Container::mNbContainers = 0;
32udword Container::mUsedRam = 0;
33#endif
34
35///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36/**
37 * Constructor. No entries allocated there.
38 */
39///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40Container::Container() : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
41{
42#ifdef CONTAINER_STATS
43 mNbContainers++;
44 mUsedRam+=sizeof(Container);
45#endif
46}
47
48///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
49/**
50 * Constructor. Also allocates a given number of entries.
51 */
52///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
53Container::Container(udword size, float growth_factor) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(growth_factor)
54{
55#ifdef CONTAINER_STATS
56 mNbContainers++;
57 mUsedRam+=sizeof(Container);
58#endif
59 SetSize(size);
60}
61
62///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63/**
64 * Copy constructor.
65 */
66///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
67Container::Container(const Container& object) : mMaxNbEntries(0), mCurNbEntries(0), mEntries(null), mGrowthFactor(2.0f)
68{
69#ifdef CONTAINER_STATS
70 mNbContainers++;
71 mUsedRam+=sizeof(Container);
72#endif
73 *this = object;
74}
75
76///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77/**
78 * Destructor. Frees everything and leaves.
79 */
80///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81Container::~Container()
82{
83 Empty();
84#ifdef CONTAINER_STATS
85 mNbContainers--;
86 mUsedRam-=GetUsedRam();
87#endif
88}
89
90///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91/**
92 * Clears the container. All stored values are deleted, and it frees used ram.
93 * \see Reset()
94 * \return Self-Reference
95 */
96///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97Container& Container::Empty()
98{
99#ifdef CONTAINER_STATS
100 mUsedRam-=mMaxNbEntries*sizeof(udword);
101#endif
102 DELETEARRAY(mEntries);
103 mCurNbEntries = mMaxNbEntries = 0;
104 return *this;
105}
106
107///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
108/**
109 * Resizes the container.
110 * \param needed [in] assume the container can be added at least "needed" values
111 * \return true if success.
112 */
113///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
114bool Container::Resize(udword needed)
115{
116#ifdef CONTAINER_STATS
117 // Subtract previous amount of bytes
118 mUsedRam-=mMaxNbEntries*sizeof(udword);
119#endif
120
121 // Get more entries
122 mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2
123 if(mMaxNbEntries<mCurNbEntries + needed) mMaxNbEntries = mCurNbEntries + needed;
124
125 // Get some bytes for new entries
126 udword* NewEntries = new udword[mMaxNbEntries];
127 CHECKALLOC(NewEntries);
128
129#ifdef CONTAINER_STATS
130 // Add current amount of bytes
131 mUsedRam+=mMaxNbEntries*sizeof(udword);
132#endif
133
134 // Copy old data if needed
135 if(mCurNbEntries) CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
136
137 // Delete old data
138 DELETEARRAY(mEntries);
139
140 // Assign new pointer
141 mEntries = NewEntries;
142
143 return true;
144}
145
146///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
147/**
148 * Sets the initial size of the container. If it already contains something, it's discarded.
149 * \param nb [in] Number of entries
150 * \return true if success
151 */
152///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
153bool Container::SetSize(udword nb)
154{
155 // Make sure it's empty
156 Empty();
157
158 // Checkings
159 if(!nb) return false;
160
161 // Initialize for nb entries
162 mMaxNbEntries = nb;
163
164 // Get some bytes for new entries
165 mEntries = new udword[mMaxNbEntries];
166 CHECKALLOC(mEntries);
167
168#ifdef CONTAINER_STATS
169 // Add current amount of bytes
170 mUsedRam+=mMaxNbEntries*sizeof(udword);
171#endif
172 return true;
173}
174
175///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
176/**
177 * Refits the container and get rid of unused bytes.
178 * \return true if success
179 */
180///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
181bool Container::Refit()
182{
183#ifdef CONTAINER_STATS
184 // Subtract previous amount of bytes
185 mUsedRam-=mMaxNbEntries*sizeof(udword);
186#endif
187
188 // Get just enough entries
189 mMaxNbEntries = mCurNbEntries;
190 if(!mMaxNbEntries) return false;
191
192 // Get just enough bytes
193 udword* NewEntries = new udword[mMaxNbEntries];
194 CHECKALLOC(NewEntries);
195
196#ifdef CONTAINER_STATS
197 // Add current amount of bytes
198 mUsedRam+=mMaxNbEntries*sizeof(udword);
199#endif
200
201 // Copy old data
202 CopyMemory(NewEntries, mEntries, mCurNbEntries*sizeof(udword));
203
204 // Delete old data
205 DELETEARRAY(mEntries);
206
207 // Assign new pointer
208 mEntries = NewEntries;
209
210 return true;
211}
212
213///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
214/**
215 * Checks whether the container already contains a given value.
216 * \param entry [in] the value to look for in the container
217 * \param location [out] a possible pointer to store the entry location
218 * \see Add(udword entry)
219 * \see Add(float entry)
220 * \see Empty()
221 * \return true if the value has been found in the container, else false.
222 */
223///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
224bool Container::Contains(udword entry, udword* location) const
225{
226 // Look for the entry
227 for(udword i=0;i<mCurNbEntries;i++)
228 {
229 if(mEntries[i]==entry)
230 {
231 if(location) *location = i;
232 return true;
233 }
234 }
235 return false;
236}
237
238///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
239/**
240 * Deletes an entry. If the container contains such an entry, it's removed.
241 * \param entry [in] the value to delete.
242 * \return true if the value has been found in the container, else false.
243 * \warning This method is arbitrary slow (O(n)) and should be used carefully. Insertion order is not preserved.
244 */
245///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
246bool Container::Delete(udword entry)
247{
248 // Look for the entry
249 for(udword i=0;i<mCurNbEntries;i++)
250 {
251 if(mEntries[i]==entry)
252 {
253 // Entry has been found at index i. The strategy is to copy the last current entry at index i, and decrement the current number of entries.
254 DeleteIndex(i);
255 return true;
256 }
257 }
258 return false;
259}
260
261///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
262/**
263 * Deletes an entry, preserving the insertion order. If the container contains such an entry, it's removed.
264 * \param entry [in] the value to delete.
265 * \return true if the value has been found in the container, else false.
266 * \warning This method is arbitrary slow (O(n)) and should be used carefully.
267 */
268///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
269bool Container::DeleteKeepingOrder(udword entry)
270{
271 // Look for the entry
272 for(udword i=0;i<mCurNbEntries;i++)
273 {
274 if(mEntries[i]==entry)
275 {
276 // Entry has been found at index i.
277 // Shift entries to preserve order. You really should use a linked list instead.
278 mCurNbEntries--;
279 for(udword j=i;j<mCurNbEntries;j++)
280 {
281 mEntries[j] = mEntries[j+1];
282 }
283 return true;
284 }
285 }
286 return false;
287}
288
289///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
290/**
291 * Gets the next entry, starting from input one.
292 * \param entry [in/out] On input, the entry to look for. On output, the next entry
293 * \param find_mode [in] wrap/clamp
294 * \return Self-Reference
295 */
296///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
297Container& Container::FindNext(udword& entry, FindMode find_mode)
298{
299 udword Location;
300 if(Contains(entry, &Location))
301 {
302 Location++;
303 if(Location==mCurNbEntries) Location = find_mode==FIND_WRAP ? 0 : mCurNbEntries-1;
304 entry = mEntries[Location];
305 }
306 return *this;
307}
308
309///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
310/**
311 * Gets the previous entry, starting from input one.
312 * \param entry [in/out] On input, the entry to look for. On output, the previous entry
313 * \param find_mode [in] wrap/clamp
314 * \return Self-Reference
315 */
316///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
317Container& Container::FindPrev(udword& entry, FindMode find_mode)
318{
319 udword Location;
320 if(Contains(entry, &Location))
321 {
322 Location--;
323 if(Location==0xffffffff) Location = find_mode==FIND_WRAP ? mCurNbEntries-1 : 0;
324 entry = mEntries[Location];
325 }
326 return *this;
327}
328
329///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
330/**
331 * Gets the ram used by the container.
332 * \return the ram used in bytes.
333 */
334///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
335udword Container::GetUsedRam() const
336{
337 return sizeof(Container) + mMaxNbEntries * sizeof(udword);
338}
339
340/*void Container::operator=(const Container& object)
341{
342 SetSize(object.GetNbEntries());
343 CopyMemory(mEntries, object.GetEntries(), mMaxNbEntries*sizeof(udword));
344 mCurNbEntries = mMaxNbEntries;
345}*/