1 #include "XPtrList.h"
2 #include "nodeClass.h"
3
4
5 void* XPtrList::sDummy = 0;
6
7
XPtrList(ListOrderingT inOrdering)8 XPtrList::XPtrList( ListOrderingT inOrdering ) {
9
10 mOrdering = inOrdering;
11 mCompFcn = 0;
12 }
13
14
15
16
Assign(const XPtrList & inList)17 void XPtrList::Assign( const XPtrList& inList ) {
18
19 UtilStr::Assign( inList );
20 }
21
22
23
24 #define __ptr( idx ) *((void**) (base + idx * 4))
25
FetchPredIndex(const void * inPtr) const26 long XPtrList::FetchPredIndex( const void* inPtr ) const {
27 long M, L = 0, R = Count()-1;
28 char* base = getCStr();
29 long order = ( mOrdering == cSortHighToLow ) ? 0x80000000 : 0;
30
31 if ( R < 0 )
32 return 0;
33 else {
34 while (L <= R) {
35
36 M = (L + R) / 2;
37
38 if ( (mCompFcn( inPtr, __ptr( M ) ) ^ order) >= 0 ) // If inPtr <= __ptr( M )...
39 R = M - 1; // Throw away right half
40 else
41 L = M + 1; // Throw away left half
42 }
43
44 if ( L > R ) // Catch the case where R+1==L
45 L = M; // In this case, M specifies the critical element
46
47 // At this point, we know L is the critical element (case: L==R or L contains M from case above)
48 if ( mCompFcn( inPtr, __ptr( L ) ) < 0 ) // If inPtr > __ptr( M )...
49 L++;
50
51 return L;
52 }
53 }
54
55
SetCompFcn(CompFunctionT inFcn,bool inSortLowToHigh)56 void XPtrList::SetCompFcn( CompFunctionT inFcn, bool inSortLowToHigh ) {
57 mCompFcn = inFcn;
58
59 RemoveAll();
60
61 if ( inSortLowToHigh )
62 mOrdering = cSortLowToHigh;
63 else
64 mOrdering = cSortHighToLow;
65
66 }
67
68
69
FindIndexOf(const void * inMatch) const70 long XPtrList::FindIndexOf( const void* inMatch ) const {
71 long i = 0;
72 char* curPtr, *endPtr;
73 void* ptr;
74
75 if ( mCompFcn ) {
76 i = FetchPredIndex( inMatch );
77 curPtr = getCStr() + 4 * i;
78 endPtr = getCStr() + length();
79 while ( curPtr < endPtr ) {
80 i++;
81 ptr = *((void**) curPtr);
82 if ( ptr == inMatch )
83 return i;
84
85 // Stop checking when we hit items that aren't equal to inMatch
86 else if ( mCompFcn( inMatch, ptr ) != 0 )
87 break;
88 curPtr += 4;
89 } }
90 else {
91 curPtr = getCStr();
92 endPtr = curPtr + length();
93
94 while ( curPtr < endPtr ) {
95 i++;
96 if ( *((void**) curPtr) == inMatch )
97 return i;
98 else
99 curPtr += 4;
100 }
101 }
102
103 return 0;
104 }
105
106
107
108
Add(const void * inPtrToAdd)109 long XPtrList::Add( const void* inPtrToAdd ) {
110 long i;
111
112 if ( mCompFcn ) {
113 i = FetchPredIndex( inPtrToAdd );
114 Insert( i*4, (char*) &inPtrToAdd, 4 );
115 return i+1; }
116 else {
117 UtilStr::Append( (char*) &inPtrToAdd, 4 );
118 return Count();
119 }
120 }
121
122
123
124
125
Add(const void * inPtrToAdd,long inN)126 void XPtrList::Add( const void* inPtrToAdd, long inN ) {
127
128 if ( inN < 0 )
129 inN = 0;
130
131 if ( inN > Count() )
132 inN = Count();
133
134 Insert( inN * 4, (char*) &inPtrToAdd, 4 );
135 }
136
137
138
139
Add(const XPtrList & inList)140 void XPtrList::Add( const XPtrList& inList ) {
141
142 if ( mOrdering == cOrderNotImportant )
143 UtilStr::Append( inList );
144 else {
145 int i, n = inList.Count();
146 for ( i = 1; i <= n; i++ )
147 Add( inList.Fetch( i ) );
148 }
149 }
150
151
152
153
operator [](const long inIndex)154 void*& XPtrList::operator[] ( const long inIndex ) {
155 long len;
156
157 if ( inIndex >= 0 ) {
158 len = mStrLen;
159 if ( inIndex >= len >> 2 ) {
160 Insert( len, '\0', ( inIndex + 1 ) * 4 - len );
161 }
162
163 return *( (void**) ( mBuf + inIndex * 4 + 1 ) ); }
164 else
165 return sDummy;
166 }
167
168
169
170
171
Remove(const void * inMatchPtr)172 bool XPtrList::Remove( const void* inMatchPtr ) {
173 long idx = FindIndexOf( inMatchPtr );
174
175 return RemoveElement( idx );
176 }
177
178
179
RemoveElement(long inIndex)180 bool XPtrList::RemoveElement( long inIndex ) {
181 char* s;
182
183 if ( inIndex > 0 && inIndex <= Count() ) {
184 inIndex--;
185 if ( mOrdering == cOrderNotImportant ) {
186 s = getCStr();
187 *( (void**) (s + inIndex * 4) ) = *( (void**) (s + length() - 4 ) );
188 Trunc( 4 ); }
189 else
190 UtilStr::Remove( inIndex * 4 + 1, 4 );
191 return true; }
192 else
193 return false;
194 }
195
196
197
198
RemoveLast()199 bool XPtrList::RemoveLast() {
200
201 if ( length() > 0 ) {
202 Trunc( 4 );
203 return true; }
204 else
205 return false;
206 }
207
208
RemoveAll()209 void XPtrList::RemoveAll() {
210 Wipe();
211 }
212
213
214
215
MoveToHead(long inIndex)216 void XPtrList::MoveToHead( long inIndex ) {
217 void* p;
218 char* s;
219
220 if ( inIndex > 1 ) {
221 if ( Fetch( inIndex, &p ) ) {
222 inIndex--;
223 s = getCStr();
224 if ( mOrdering == cOrderNotImportant )
225 *( (void**) (s + inIndex * 4) ) = *( (void**) s);
226 else
227 UtilStr::Move( s+4, s, inIndex * 4 );
228 *( (void**) s) = p;
229 }
230 }
231 }
232
233
234
235
Fetch(long inIndex) const236 void* XPtrList::Fetch( long inIndex ) const {
237 if ( inIndex >= 1 && inIndex <= length() >> 2 )
238 return *( (void**) (getCStr() + ( inIndex - 1 ) * 4) );
239 else
240 return 0;
241 }
242
243
Fetch(long inIndex,void ** ioPtrDest) const244 bool XPtrList::Fetch( long inIndex, void** ioPtrDest ) const {
245
246 if ( ioPtrDest ) {
247 if ( inIndex >= 1 && inIndex <= length() / 4 ) {
248 *ioPtrDest = *( (void**) (getCStr() + ( inIndex - 1 ) * 4) );
249 return true; }
250 else
251 *ioPtrDest = 0;
252 }
253
254 return false;
255 }
256
257
258
259
260
261
262 #include <stdio.h>
Randomize()263 void XPtrList::Randomize() {
264 void* temp, **ptrArray = (void**) getCStr();
265 long i, randIdx, n = Count();
266
267 for ( i = 0; i < n; i++ ) {
268 randIdx = nodeClass::Rnd( 1, n );
269 temp = ptrArray[ i ];
270 ptrArray[ i ] = ptrArray[ randIdx-1 ];
271 ptrArray[ randIdx-1 ] = temp;
272 }
273 }
274
275