1 /**CFile****************************************************************
2 Copyright (c) The Regents of the University of California. All rights reserved.
3
4 Permission is hereby granted, without written agreement and without license or
5 royalty fees, to use, copy, modify, and distribute this software and its
6 documentation for any purpose, provided that the above copyright notice and
7 the following two paragraphs appear in all copies of this software.
8
9 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
10 DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
11 THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
12 CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13
14 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
15 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
17 AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
18 SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
19
20
21 FileName [vecPtr.h]
22
23 SystemName [ABC: Logic synthesis and verification system.]
24
25 PackageName [Resizable arrays.]
26
27 Synopsis [Resizable arrays of generic pointers.]
28
29 Author [Alan Mishchenko]
30
31 Affiliation [UC Berkeley]
32
33 Date [Ver. 1.0. Started - June 20, 2005.]
34
35 Revision [$Id: vecPtr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
36
37 ***********************************************************************/
38
39 #ifndef __VEC_PTR_H__
40 #define __VEC_PTR_H__
41
42 ////////////////////////////////////////////////////////////////////////
43 /// INCLUDES ///
44 ////////////////////////////////////////////////////////////////////////
45
46 #include <stdio.h>
47
48 ////////////////////////////////////////////////////////////////////////
49 /// PARAMETERS ///
50 ////////////////////////////////////////////////////////////////////////
51
52 ////////////////////////////////////////////////////////////////////////
53 /// BASIC TYPES ///
54 ////////////////////////////////////////////////////////////////////////
55
56 typedef struct Vec_Ptr_t_ Vec_Ptr_t;
57 struct Vec_Ptr_t_
58 {
59 int nCap;
60 int nSize;
61 void ** pArray;
62 };
63
64 ////////////////////////////////////////////////////////////////////////
65 /// MACRO DEFINITIONS ///
66 ////////////////////////////////////////////////////////////////////////
67
68 // iterators through entries
69 #define Vec_PtrForEachEntry( vVec, pEntry, i ) \
70 for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
71 #define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \
72 for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
73 #define Vec_PtrForEachEntryStop( vVec, pEntry, i, Stop ) \
74 for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
75 #define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop ) \
76 for ( i = Start; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
77 #define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \
78 for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- )
79
80 ////////////////////////////////////////////////////////////////////////
81 /// FUNCTION DEFINITIONS ///
82 ////////////////////////////////////////////////////////////////////////
83
84 /**Function*************************************************************
85
86 Synopsis [Allocates a vector with the given capacity.]
87
88 Description []
89
90 SideEffects []
91
92 SeeAlso []
93
94 ***********************************************************************/
Vec_PtrAlloc(int nCap)95 static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap )
96 {
97 Vec_Ptr_t * p;
98 p = ALLOC( Vec_Ptr_t, 1 );
99 if ( nCap > 0 && nCap < 8 )
100 nCap = 8;
101 p->nSize = 0;
102 p->nCap = nCap;
103 p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
104 return p;
105 }
106
107 /**Function*************************************************************
108
109 Synopsis [Allocates a vector with the given size and cleans it.]
110
111 Description []
112
113 SideEffects []
114
115 SeeAlso []
116
117 ***********************************************************************/
Vec_PtrStart(int nSize)118 static inline Vec_Ptr_t * Vec_PtrStart( int nSize )
119 {
120 Vec_Ptr_t * p;
121 p = Vec_PtrAlloc( nSize );
122 p->nSize = nSize;
123 memset( p->pArray, 0, sizeof(void *) * nSize );
124 return p;
125 }
126
127 /**Function*************************************************************
128
129 Synopsis [Creates the vector from an integer array of the given size.]
130
131 Description []
132
133 SideEffects []
134
135 SeeAlso []
136
137 ***********************************************************************/
Vec_PtrAllocArray(void ** pArray,int nSize)138 static inline Vec_Ptr_t * Vec_PtrAllocArray( void ** pArray, int nSize )
139 {
140 Vec_Ptr_t * p;
141 p = ALLOC( Vec_Ptr_t, 1 );
142 p->nSize = nSize;
143 p->nCap = nSize;
144 p->pArray = pArray;
145 return p;
146 }
147
148 /**Function*************************************************************
149
150 Synopsis [Creates the vector from an integer array of the given size.]
151
152 Description []
153
154 SideEffects []
155
156 SeeAlso []
157
158 ***********************************************************************/
Vec_PtrAllocArrayCopy(void ** pArray,int nSize)159 static inline Vec_Ptr_t * Vec_PtrAllocArrayCopy( void ** pArray, int nSize )
160 {
161 Vec_Ptr_t * p;
162 p = ALLOC( Vec_Ptr_t, 1 );
163 p->nSize = nSize;
164 p->nCap = nSize;
165 p->pArray = ALLOC( void *, nSize );
166 memcpy( p->pArray, pArray, sizeof(void *) * nSize );
167 return p;
168 }
169
170 /**Function*************************************************************
171
172 Synopsis [Allocates the array of simulation info.]
173
174 Description [Allocates the array containing given number of entries,
175 each of which contains given number of unsigned words of simulation data.
176 The resulting array can be freed using regular procedure Vec_PtrFree().
177 It is the responsibility of the user to ensure this array is never grown.]
178
179 SideEffects []
180
181 SeeAlso []
182
183 ***********************************************************************/
Vec_PtrAllocSimInfo(int nEntries,int nWords)184 static inline Vec_Ptr_t * Vec_PtrAllocSimInfo( int nEntries, int nWords )
185 {
186 void ** pMemory;
187 unsigned * pInfo;
188 int i;
189 pMemory = (void **)ALLOC( char, (sizeof(void *) + sizeof(unsigned) * nWords) * nEntries );
190 pInfo = (unsigned *)(pMemory + nEntries);
191 for ( i = 0; i < nEntries; i++ )
192 pMemory[i] = pInfo + i * nWords;
193 return Vec_PtrAllocArray( pMemory, nEntries );
194 }
195
196 /**Function*************************************************************
197
198 Synopsis [Allocates the array of truth tables for the given number of vars.]
199
200 Description []
201
202 SideEffects []
203
204 SeeAlso []
205
206 ***********************************************************************/
Vec_PtrAllocTruthTables(int nVars)207 static inline Vec_Ptr_t * Vec_PtrAllocTruthTables( int nVars )
208 {
209 Vec_Ptr_t * p;
210 unsigned Masks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
211 unsigned * pTruth;
212 int i, k, nWords;
213 nWords = (nVars <= 5 ? 1 : (1 << (nVars - 5)));
214 p = Vec_PtrAllocSimInfo( nVars, nWords );
215 for ( i = 0; i < nVars; i++ )
216 {
217 pTruth = (unsigned *)p->pArray[i];
218 if ( i < 5 )
219 {
220 for ( k = 0; k < nWords; k++ )
221 pTruth[k] = Masks[i];
222 }
223 else
224 {
225 for ( k = 0; k < nWords; k++ )
226 if ( k & (1 << (i-5)) )
227 pTruth[k] = ~(unsigned)0;
228 else
229 pTruth[k] = 0;
230 }
231 }
232 return p;
233 }
234
235 /**Function*************************************************************
236
237 Synopsis [Duplicates the integer array.]
238
239 Description []
240
241 SideEffects []
242
243 SeeAlso []
244
245 ***********************************************************************/
Vec_PtrDup(Vec_Ptr_t * pVec)246 static inline Vec_Ptr_t * Vec_PtrDup( Vec_Ptr_t * pVec )
247 {
248 Vec_Ptr_t * p;
249 p = ALLOC( Vec_Ptr_t, 1 );
250 p->nSize = pVec->nSize;
251 p->nCap = pVec->nCap;
252 p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
253 memcpy( p->pArray, pVec->pArray, sizeof(void *) * pVec->nSize );
254 return p;
255 }
256
257 /**Function*************************************************************
258
259 Synopsis [Transfers the array into another vector.]
260
261 Description []
262
263 SideEffects []
264
265 SeeAlso []
266
267 ***********************************************************************/
Vec_PtrDupArray(Vec_Ptr_t * pVec)268 static inline Vec_Ptr_t * Vec_PtrDupArray( Vec_Ptr_t * pVec )
269 {
270 Vec_Ptr_t * p;
271 p = ALLOC( Vec_Ptr_t, 1 );
272 p->nSize = pVec->nSize;
273 p->nCap = pVec->nCap;
274 p->pArray = pVec->pArray;
275 pVec->nSize = 0;
276 pVec->nCap = 0;
277 pVec->pArray = NULL;
278 return p;
279 }
280
281 /**Function*************************************************************
282
283 Synopsis [Frees the vector.]
284
285 Description []
286
287 SideEffects []
288
289 SeeAlso []
290
291 ***********************************************************************/
Vec_PtrFree(Vec_Ptr_t * p)292 static inline void Vec_PtrFree( Vec_Ptr_t * p )
293 {
294 FREE( p->pArray );
295 FREE( p );
296 }
297
298 /**Function*************************************************************
299
300 Synopsis []
301
302 Description []
303
304 SideEffects []
305
306 SeeAlso []
307
308 ***********************************************************************/
Vec_PtrReleaseArray(Vec_Ptr_t * p)309 static inline void ** Vec_PtrReleaseArray( Vec_Ptr_t * p )
310 {
311 void ** pArray = p->pArray;
312 p->nCap = 0;
313 p->nSize = 0;
314 p->pArray = NULL;
315 return pArray;
316 }
317
318 /**Function*************************************************************
319
320 Synopsis []
321
322 Description []
323
324 SideEffects []
325
326 SeeAlso []
327
328 ***********************************************************************/
Vec_PtrArray(Vec_Ptr_t * p)329 static inline void ** Vec_PtrArray( Vec_Ptr_t * p )
330 {
331 return p->pArray;
332 }
333
334 /**Function*************************************************************
335
336 Synopsis []
337
338 Description []
339
340 SideEffects []
341
342 SeeAlso []
343
344 ***********************************************************************/
Vec_PtrSize(Vec_Ptr_t * p)345 static inline int Vec_PtrSize( Vec_Ptr_t * p )
346 {
347 return p->nSize;
348 }
349
350 /**Function*************************************************************
351
352 Synopsis []
353
354 Description []
355
356 SideEffects []
357
358 SeeAlso []
359
360 ***********************************************************************/
Vec_PtrEntry(Vec_Ptr_t * p,int i)361 static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
362 {
363 assert( i >= 0 && i < p->nSize );
364 return p->pArray[i];
365 }
366
367 /**Function*************************************************************
368
369 Synopsis [Resizes the array of simulation info.]
370
371 Description []
372
373 SideEffects []
374
375 SeeAlso []
376
377 ***********************************************************************/
Vec_PtrDoubleSimInfo(Vec_Ptr_t * vInfo)378 static inline void Vec_PtrDoubleSimInfo( Vec_Ptr_t * vInfo )
379 {
380 Vec_Ptr_t * vInfoNew;
381 int nWords;
382 assert( Vec_PtrSize(vInfo) > 2 );
383 // get the new array
384 nWords = (unsigned *)Vec_PtrEntry(vInfo,1) - (unsigned *)Vec_PtrEntry(vInfo,0);
385 vInfoNew = Vec_PtrAllocSimInfo( 2*Vec_PtrSize(vInfo), nWords );
386 // copy the simulation info
387 memcpy( Vec_PtrEntry(vInfoNew,0), Vec_PtrEntry(vInfo,0), Vec_PtrSize(vInfo) * nWords * 4 );
388 // replace the array
389 free( vInfo->pArray );
390 vInfo->pArray = vInfoNew->pArray;
391 vInfo->nSize *= 2;
392 vInfo->nCap *= 2;
393 // free the old array
394 vInfoNew->pArray = NULL;
395 free( vInfoNew );
396 }
397
398 /**Function*************************************************************
399
400 Synopsis []
401
402 Description []
403
404 SideEffects []
405
406 SeeAlso []
407
408 ***********************************************************************/
Vec_PtrEntryP(Vec_Ptr_t * p,int i)409 static inline void ** Vec_PtrEntryP( Vec_Ptr_t * p, int i )
410 {
411 assert( i >= 0 && i < p->nSize );
412 return p->pArray + i;
413 }
414
415 /**Function*************************************************************
416
417 Synopsis []
418
419 Description []
420
421 SideEffects []
422
423 SeeAlso []
424
425 ***********************************************************************/
Vec_PtrWriteEntry(Vec_Ptr_t * p,int i,void * Entry)426 static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry )
427 {
428 assert( i >= 0 && i < p->nSize );
429 p->pArray[i] = Entry;
430 }
431
432 /**Function*************************************************************
433
434 Synopsis []
435
436 Description []
437
438 SideEffects []
439
440 SeeAlso []
441
442 ***********************************************************************/
Vec_PtrEntryLast(Vec_Ptr_t * p)443 static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p )
444 {
445 assert( p->nSize > 0 );
446 return p->pArray[p->nSize-1];
447 }
448
449 /**Function*************************************************************
450
451 Synopsis [Resizes the vector to the given capacity.]
452
453 Description []
454
455 SideEffects []
456
457 SeeAlso []
458
459 ***********************************************************************/
Vec_PtrGrow(Vec_Ptr_t * p,int nCapMin)460 static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin )
461 {
462 if ( p->nCap >= nCapMin )
463 return;
464 p->pArray = REALLOC( void *, p->pArray, nCapMin );
465 p->nCap = nCapMin;
466 }
467
468 /**Function*************************************************************
469
470 Synopsis [Fills the vector with given number of entries.]
471
472 Description []
473
474 SideEffects []
475
476 SeeAlso []
477
478 ***********************************************************************/
Vec_PtrFill(Vec_Ptr_t * p,int nSize,void * Entry)479 static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry )
480 {
481 int i;
482 Vec_PtrGrow( p, nSize );
483 for ( i = 0; i < nSize; i++ )
484 p->pArray[i] = Entry;
485 p->nSize = nSize;
486 }
487
488 /**Function*************************************************************
489
490 Synopsis [Fills the vector with given number of entries.]
491
492 Description []
493
494 SideEffects []
495
496 SeeAlso []
497
498 ***********************************************************************/
Vec_PtrFillExtra(Vec_Ptr_t * p,int nSize,void * Entry)499 static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
500 {
501 int i;
502 if ( p->nSize >= nSize )
503 return;
504 assert( p->nSize < nSize );
505 if ( 2 * p->nSize > nSize )
506 Vec_PtrGrow( p, 2 * nSize );
507 else
508 Vec_PtrGrow( p, nSize );
509 for ( i = p->nSize; i < nSize; i++ )
510 p->pArray[i] = Entry;
511 p->nSize = nSize;
512 }
513
514 /**Function*************************************************************
515
516 Synopsis [Returns the entry even if the place not exist.]
517
518 Description []
519
520 SideEffects []
521
522 SeeAlso []
523
524 ***********************************************************************/
Vec_PtrGetEntry(Vec_Ptr_t * p,int i)525 static inline void * Vec_PtrGetEntry( Vec_Ptr_t * p, int i )
526 {
527 Vec_PtrFillExtra( p, i + 1, NULL );
528 return Vec_PtrEntry( p, i );
529 }
530
531 /**Function*************************************************************
532
533 Synopsis [Inserts the entry even if the place does not exist.]
534
535 Description []
536
537 SideEffects []
538
539 SeeAlso []
540
541 ***********************************************************************/
Vec_PtrSetEntry(Vec_Ptr_t * p,int i,void * Entry)542 static inline void Vec_PtrSetEntry( Vec_Ptr_t * p, int i, void * Entry )
543 {
544 Vec_PtrFillExtra( p, i + 1, NULL );
545 Vec_PtrWriteEntry( p, i, Entry );
546 }
547
548 /**Function*************************************************************
549
550 Synopsis []
551
552 Description []
553
554 SideEffects []
555
556 SeeAlso []
557
558 ***********************************************************************/
Vec_PtrShrink(Vec_Ptr_t * p,int nSizeNew)559 static inline void Vec_PtrShrink( Vec_Ptr_t * p, int nSizeNew )
560 {
561 assert( p->nSize >= nSizeNew );
562 p->nSize = nSizeNew;
563 }
564
565 /**Function*************************************************************
566
567 Synopsis []
568
569 Description []
570
571 SideEffects []
572
573 SeeAlso []
574
575 ***********************************************************************/
Vec_PtrClear(Vec_Ptr_t * p)576 static inline void Vec_PtrClear( Vec_Ptr_t * p )
577 {
578 p->nSize = 0;
579 }
580
581 /**Function*************************************************************
582
583 Synopsis [Copies the interger array.]
584
585 Description []
586
587 SideEffects []
588
589 SeeAlso []
590
591 ***********************************************************************/
Vec_PtrCopy(Vec_Ptr_t * pDest,Vec_Ptr_t * pSour)592 static inline void Vec_PtrCopy( Vec_Ptr_t * pDest, Vec_Ptr_t * pSour )
593 {
594 pDest->nSize = 0;
595 Vec_PtrGrow( pDest, pSour->nSize );
596 memcpy( pDest->pArray, pSour->pArray, sizeof(void *) * pSour->nSize );
597 pDest->nSize = pSour->nSize;
598 }
599
600 /**Function*************************************************************
601
602 Synopsis []
603
604 Description []
605
606 SideEffects []
607
608 SeeAlso []
609
610 ***********************************************************************/
Vec_PtrPush(Vec_Ptr_t * p,void * Entry)611 static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry )
612 {
613 if ( p->nSize == p->nCap )
614 {
615 if ( p->nCap < 16 )
616 Vec_PtrGrow( p, 16 );
617 else
618 Vec_PtrGrow( p, 2 * p->nCap );
619 }
620 p->pArray[p->nSize++] = Entry;
621 }
622
623 /**Function*************************************************************
624
625 Synopsis []
626
627 Description []
628
629 SideEffects []
630
631 SeeAlso []
632
633 ***********************************************************************/
Vec_PtrPushUnique(Vec_Ptr_t * p,void * Entry)634 static inline int Vec_PtrPushUnique( Vec_Ptr_t * p, void * Entry )
635 {
636 int i;
637 for ( i = 0; i < p->nSize; i++ )
638 if ( p->pArray[i] == Entry )
639 return 1;
640 Vec_PtrPush( p, Entry );
641 return 0;
642 }
643
644 /**Function*************************************************************
645
646 Synopsis [Returns the last entry and removes it from the list.]
647
648 Description []
649
650 SideEffects []
651
652 SeeAlso []
653
654 ***********************************************************************/
Vec_PtrPop(Vec_Ptr_t * p)655 static inline void * Vec_PtrPop( Vec_Ptr_t * p )
656 {
657 assert( p->nSize > 0 );
658 return p->pArray[--p->nSize];
659 }
660
661 /**Function*************************************************************
662
663 Synopsis [Find entry.]
664
665 Description []
666
667 SideEffects []
668
669 SeeAlso []
670
671 ***********************************************************************/
Vec_PtrFind(Vec_Ptr_t * p,void * Entry)672 static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry )
673 {
674 int i;
675 for ( i = 0; i < p->nSize; i++ )
676 if ( p->pArray[i] == Entry )
677 return i;
678 return -1;
679 }
680
681 /**Function*************************************************************
682
683 Synopsis []
684
685 Description []
686
687 SideEffects []
688
689 SeeAlso []
690
691 ***********************************************************************/
Vec_PtrRemove(Vec_Ptr_t * p,void * Entry)692 static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry )
693 {
694 int i;
695 // delete assuming that it is closer to the end
696 for ( i = p->nSize - 1; i >= 0; i-- )
697 if ( p->pArray[i] == Entry )
698 break;
699 assert( i >= 0 );
700 /*
701 // delete assuming that it is closer to the beginning
702 for ( i = 0; i < p->nSize; i++ )
703 if ( p->pArray[i] == Entry )
704 break;
705 assert( i < p->nSize );
706 */
707 for ( i++; i < p->nSize; i++ )
708 p->pArray[i-1] = p->pArray[i];
709 p->nSize--;
710 }
711
712 /**Function*************************************************************
713
714 Synopsis [Moves the first nItems to the end.]
715
716 Description []
717
718 SideEffects []
719
720 SeeAlso []
721
722 ***********************************************************************/
Vec_PtrReorder(Vec_Ptr_t * p,int nItems)723 static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
724 {
725 assert( nItems < p->nSize );
726 Vec_PtrGrow( p, nItems + p->nSize );
727 memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) );
728 memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) );
729 }
730
731 /**Function*************************************************************
732
733 Synopsis [Sorting the entries by their integer value.]
734
735 Description []
736
737 SideEffects []
738
739 SeeAlso []
740
741 ***********************************************************************/
Vec_PtrSort(Vec_Ptr_t * p,int (* Vec_PtrSortCompare)())742 static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
743 {
744 if ( p->nSize < 2 )
745 return;
746 qsort( (void *)p->pArray, p->nSize, sizeof(void *),
747 (int (*)(const void *, const void *)) Vec_PtrSortCompare );
748 }
749
750 /**Function*************************************************************
751
752 Synopsis [Sorting the entries by their integer value.]
753
754 Description []
755
756 SideEffects []
757
758 SeeAlso []
759
760 ***********************************************************************/
Vec_PtrUniqify(Vec_Ptr_t * p,int (* Vec_PtrSortCompare)())761 static inline void Vec_PtrUniqify( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
762 {
763 int i, k;
764 if ( p->nSize < 2 )
765 return;
766 qsort( (void *)p->pArray, p->nSize, sizeof(void *),
767 (int (*)(const void *, const void *)) Vec_PtrSortCompare );
768 for ( i = k = 1; i < p->nSize; i++ )
769 if ( p->pArray[i] != p->pArray[i-1] )
770 p->pArray[k++] = p->pArray[i];
771 p->nSize = k;
772 }
773
774 #endif
775
776
777 ////////////////////////////////////////////////////////////////////////
778 /// END OF FILE ///
779 ////////////////////////////////////////////////////////////////////////
780
781