2 * ICE / OPCODE - Optimized Collision Detection
3 * http://www.codercorner.com/Opcode.htm
5 * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com
7 This software is provided 'as-is', without any express or implied warranty.
8 In no event will the authors be held liable for any damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it freely,
11 subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15 3. This notice may not be removed or altered from any source distribution.
17 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 * Contains a simple container class.
20 * \file IceContainer.h
21 * \author Pierre Terdiman
22 * \date February, 5, 2000
24 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28 #ifndef __ICECONTAINER_H__
29 #define __ICECONTAINER_H__
31 #define CONTAINER_STATS
38 FIND_FORCE_DWORD = 0x7fffffff
41 class ICECORE_API Container
44 // Constructor / Destructor
46 Container(const Container& object);
47 Container(udword size, float growth_factor);
50 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
52 * A O(1) method to add a value in the container. The container is automatically resized if needed.
53 * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
54 * costs a lot more than the call overhead...
56 * \param entry [in] a udword to store in the container
57 * \see Add(float entry)
59 * \see Contains(udword entry)
60 * \return Self-Reference
62 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63 inline_ Container& Add(udword entry)
66 if(mCurNbEntries==mMaxNbEntries) Resize();
69 mEntries[mCurNbEntries++] = entry;
73 inline_ Container& Add(const udword* entries, udword nb)
76 if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
79 CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword));
84 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86 * A O(1) method to add a value in the container. The container is automatically resized if needed.
87 * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation
88 * costs a lot more than the call overhead...
90 * \param entry [in] a float to store in the container
91 * \see Add(udword entry)
93 * \see Contains(udword entry)
94 * \return Self-Reference
96 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
97 inline_ Container& Add(float entry)
100 if(mCurNbEntries==mMaxNbEntries) Resize();
103 mEntries[mCurNbEntries++] = IR(entry);
107 inline_ Container& Add(const float* entries, udword nb)
110 if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb);
113 CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float));
118 //! Add unique [slow]
119 inline_ Container& AddUnique(udword entry)
121 if(!Contains(entry)) Add(entry);
125 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
127 * Clears the container. All stored values are deleted, and it frees used ram.
129 * \return Self-Reference
131 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
134 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
136 * Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again.
137 * That's a kind of temporal coherence.
140 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
143 // Avoid the write if possible
145 if(mCurNbEntries) mCurNbEntries = 0;
149 inline_ void ForceSize(udword size)
151 mCurNbEntries = size;
154 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
156 * Sets the initial size of the container. If it already contains something, it's discarded.
157 * \param nb [in] Number of entries
158 * \return true if success
160 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
161 bool SetSize(udword nb);
163 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
165 * Refits the container and get rid of unused bytes.
166 * \return true if success
168 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
171 // Checks whether the container already contains a given value.
172 bool Contains(udword entry, udword* location=null) const;
173 // Deletes an entry - doesn't preserve insertion order.
174 bool Delete(udword entry);
175 // Deletes an entry - does preserve insertion order.
176 bool DeleteKeepingOrder(udword entry);
177 //! Deletes the very last entry.
178 inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; }
179 //! Deletes the entry whose index is given
180 inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; }
183 Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP);
184 Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP);
186 inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries.
187 inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry
188 inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries.
190 inline_ udword GetFirst() const { return mEntries[0]; }
191 inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; }
194 inline_ float GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor
195 inline_ void SetGrowthFactor(float growth) { mGrowthFactor = growth; } //!< Sets the growth factor
196 inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full
197 inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty
199 //! Read-access as an array
200 inline_ udword operator[](udword i) const { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
201 //! Write-access as an array
202 inline_ udword& operator[](udword i) { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; }
205 udword GetUsedRam() const;
207 //! Operator for "Container A = Container B"
208 void operator = (const Container& object);
210 #ifdef CONTAINER_STATS
211 inline_ udword GetNbContainers() const { return mNbContainers; }
212 inline_ udword GetTotalBytes() const { return mUsedRam; }
215 static udword mNbContainers; //!< Number of containers around
216 static udword mUsedRam; //!< Amount of bytes used by containers in the system
220 bool Resize(udword needed=1);
222 udword mMaxNbEntries; //!< Maximum possible number of entries
223 udword mCurNbEntries; //!< Current number of entries
224 udword* mEntries; //!< List of entries
225 float mGrowthFactor; //!< Resize: new number of entries = old number * mGrowthFactor
228 #endif // __ICECONTAINER_H__