diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ode-0.9/OPCODE/Ice/IceContainer.h | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/libraries/ode-0.9/OPCODE/Ice/IceContainer.h b/libraries/ode-0.9/OPCODE/Ice/IceContainer.h new file mode 100644 index 0000000..d726c2a --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceContainer.h | |||
@@ -0,0 +1,212 @@ | |||
1 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
2 | /** | ||
3 | * Contains a simple container class. | ||
4 | * \file IceContainer.h | ||
5 | * \author Pierre Terdiman | ||
6 | * \date February, 5, 2000 | ||
7 | */ | ||
8 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
9 | |||
10 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
11 | // Include Guard | ||
12 | #ifndef __ICECONTAINER_H__ | ||
13 | #define __ICECONTAINER_H__ | ||
14 | |||
15 | #define CONTAINER_STATS | ||
16 | |||
17 | enum FindMode | ||
18 | { | ||
19 | FIND_CLAMP, | ||
20 | FIND_WRAP, | ||
21 | |||
22 | FIND_FORCE_DWORD = 0x7fffffff | ||
23 | }; | ||
24 | |||
25 | class ICECORE_API Container | ||
26 | { | ||
27 | public: | ||
28 | // Constructor / Destructor | ||
29 | Container(); | ||
30 | Container(const Container& object); | ||
31 | Container(udword size, float growth_factor); | ||
32 | ~Container(); | ||
33 | // Management | ||
34 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
35 | /** | ||
36 | * A O(1) method to add a value in the container. The container is automatically resized if needed. | ||
37 | * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation | ||
38 | * costs a lot more than the call overhead... | ||
39 | * | ||
40 | * \param entry [in] a udword to store in the container | ||
41 | * \see Add(float entry) | ||
42 | * \see Empty() | ||
43 | * \see Contains(udword entry) | ||
44 | * \return Self-Reference | ||
45 | */ | ||
46 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
47 | inline_ Container& Add(udword entry) | ||
48 | { | ||
49 | // Resize if needed | ||
50 | if(mCurNbEntries==mMaxNbEntries) Resize(); | ||
51 | |||
52 | // Add new entry | ||
53 | mEntries[mCurNbEntries++] = entry; | ||
54 | return *this; | ||
55 | } | ||
56 | |||
57 | inline_ Container& Add(const udword* entries, udword nb) | ||
58 | { | ||
59 | // Resize if needed | ||
60 | if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb); | ||
61 | |||
62 | // Add new entry | ||
63 | CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(udword)); | ||
64 | mCurNbEntries+=nb; | ||
65 | return *this; | ||
66 | } | ||
67 | |||
68 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
69 | /** | ||
70 | * A O(1) method to add a value in the container. The container is automatically resized if needed. | ||
71 | * The method is inline, not the resize. The call overhead happens on resizes only, which is not a problem since the resizing operation | ||
72 | * costs a lot more than the call overhead... | ||
73 | * | ||
74 | * \param entry [in] a float to store in the container | ||
75 | * \see Add(udword entry) | ||
76 | * \see Empty() | ||
77 | * \see Contains(udword entry) | ||
78 | * \return Self-Reference | ||
79 | */ | ||
80 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
81 | inline_ Container& Add(float entry) | ||
82 | { | ||
83 | // Resize if needed | ||
84 | if(mCurNbEntries==mMaxNbEntries) Resize(); | ||
85 | |||
86 | // Add new entry | ||
87 | mEntries[mCurNbEntries++] = IR(entry); | ||
88 | return *this; | ||
89 | } | ||
90 | |||
91 | inline_ Container& Add(const float* entries, udword nb) | ||
92 | { | ||
93 | // Resize if needed | ||
94 | if(mCurNbEntries+nb>mMaxNbEntries) Resize(nb); | ||
95 | |||
96 | // Add new entry | ||
97 | CopyMemory(&mEntries[mCurNbEntries], entries, nb*sizeof(float)); | ||
98 | mCurNbEntries+=nb; | ||
99 | return *this; | ||
100 | } | ||
101 | |||
102 | //! Add unique [slow] | ||
103 | inline_ Container& AddUnique(udword entry) | ||
104 | { | ||
105 | if(!Contains(entry)) Add(entry); | ||
106 | return *this; | ||
107 | } | ||
108 | |||
109 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
110 | /** | ||
111 | * Clears the container. All stored values are deleted, and it frees used ram. | ||
112 | * \see Reset() | ||
113 | * \return Self-Reference | ||
114 | */ | ||
115 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
116 | Container& Empty(); | ||
117 | |||
118 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
119 | /** | ||
120 | * Resets the container. Stored values are discarded but the buffer is kept so that further calls don't need resizing again. | ||
121 | * That's a kind of temporal coherence. | ||
122 | * \see Empty() | ||
123 | */ | ||
124 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
125 | inline_ void Reset() | ||
126 | { | ||
127 | // Avoid the write if possible | ||
128 | // ### CMOV | ||
129 | if(mCurNbEntries) mCurNbEntries = 0; | ||
130 | } | ||
131 | |||
132 | // HANDLE WITH CARE | ||
133 | inline_ void ForceSize(udword size) | ||
134 | { | ||
135 | mCurNbEntries = size; | ||
136 | } | ||
137 | |||
138 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
139 | /** | ||
140 | * Sets the initial size of the container. If it already contains something, it's discarded. | ||
141 | * \param nb [in] Number of entries | ||
142 | * \return true if success | ||
143 | */ | ||
144 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
145 | bool SetSize(udword nb); | ||
146 | |||
147 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
148 | /** | ||
149 | * Refits the container and get rid of unused bytes. | ||
150 | * \return true if success | ||
151 | */ | ||
152 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
153 | bool Refit(); | ||
154 | |||
155 | // Checks whether the container already contains a given value. | ||
156 | bool Contains(udword entry, udword* location=null) const; | ||
157 | // Deletes an entry - doesn't preserve insertion order. | ||
158 | bool Delete(udword entry); | ||
159 | // Deletes an entry - does preserve insertion order. | ||
160 | bool DeleteKeepingOrder(udword entry); | ||
161 | //! Deletes the very last entry. | ||
162 | inline_ void DeleteLastEntry() { if(mCurNbEntries) mCurNbEntries--; } | ||
163 | //! Deletes the entry whose index is given | ||
164 | inline_ void DeleteIndex(udword index) { mEntries[index] = mEntries[--mCurNbEntries]; } | ||
165 | |||
166 | // Helpers | ||
167 | Container& FindNext(udword& entry, FindMode find_mode=FIND_CLAMP); | ||
168 | Container& FindPrev(udword& entry, FindMode find_mode=FIND_CLAMP); | ||
169 | // Data access. | ||
170 | inline_ udword GetNbEntries() const { return mCurNbEntries; } //!< Returns the current number of entries. | ||
171 | inline_ udword GetEntry(udword i) const { return mEntries[i]; } //!< Returns ith entry | ||
172 | inline_ udword* GetEntries() const { return mEntries; } //!< Returns the list of entries. | ||
173 | |||
174 | inline_ udword GetFirst() const { return mEntries[0]; } | ||
175 | inline_ udword GetLast() const { return mEntries[mCurNbEntries-1]; } | ||
176 | |||
177 | // Growth control | ||
178 | inline_ float GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor | ||
179 | inline_ void SetGrowthFactor(float growth) { mGrowthFactor = growth; } //!< Sets the growth factor | ||
180 | inline_ bool IsFull() const { return mCurNbEntries==mMaxNbEntries; } //!< Checks the container is full | ||
181 | inline_ BOOL IsNotEmpty() const { return mCurNbEntries; } //!< Checks the container is empty | ||
182 | |||
183 | //! Read-access as an array | ||
184 | inline_ udword operator[](udword i) const { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; } | ||
185 | //! Write-access as an array | ||
186 | inline_ udword& operator[](udword i) { ASSERT(i>=0 && i<mCurNbEntries); return mEntries[i]; } | ||
187 | |||
188 | // Stats | ||
189 | udword GetUsedRam() const; | ||
190 | |||
191 | //! Operator for "Container A = Container B" | ||
192 | //void operator = (const Container& object); | ||
193 | |||
194 | #ifdef CONTAINER_STATS | ||
195 | inline_ udword GetNbContainers() const { return mNbContainers; } | ||
196 | inline_ udword GetTotalBytes() const { return mUsedRam; } | ||
197 | private: | ||
198 | |||
199 | static udword mNbContainers; //!< Number of containers around | ||
200 | static udword mUsedRam; //!< Amount of bytes used by containers in the system | ||
201 | #endif | ||
202 | private: | ||
203 | // Resizing | ||
204 | bool Resize(udword needed=1); | ||
205 | // Data | ||
206 | udword mMaxNbEntries; //!< Maximum possible number of entries | ||
207 | udword mCurNbEntries; //!< Current number of entries | ||
208 | udword* mEntries; //!< List of entries | ||
209 | float mGrowthFactor; //!< Resize: new number of entries = old number * mGrowthFactor | ||
210 | }; | ||
211 | |||
212 | #endif // __ICECONTAINER_H__ | ||