Object-c 的TList类,翻译delphi版

为什么要实现一个tlist类,object-c自带nsarray和nsmutarray类,但这两个类都只能管理id类型也就是必须是nsobject或者是继承自nsobject的类型,因为在addobject和removeobject的时候,会去调用nsobject的retain和release方法对计数器加1和减1。有些时候它替我们管理,比较方便,但在某些时候就觉得它多管闲事了,感觉不通用。因此,我们更希望一个能存放任意指针类型的tlist类,下面附代码:

头文件:

#define MaxListSize (int)21474883647/6

typedef enum
{
        lnAdded,
        lnExtracted,
        lnDeleted
}TListNotifyication;

typedef void** PPointerList;

@protocol TListSortCompare
+(int)_Sort:(void*)Item1:(void*)Item2;
@end;

@interface TList : NSObject
{
        @private
        PPointerList FList;
        int FCount;
        int FCapacity;
}
//protected function
-(void)_Notify:(void*)P:(TListNotifyication)Action;
//protected function virtual
-(void)_Grow;
//public function
-(void)dealloc;
-(int)Add:(void*)Item;
-(void)Delete:(int)Index;
-(TList*)Expaned;
-(void*)Extract:(void*)Item;
-(void*)First;
-(int)IndexOf:(void*)Item;
-(void)Insert:(int)Index:(void*)Item;
-(void*)Last;
-(void)Move:(int)CurIndex:(int)NewIndex;
-(int)Remove:(void*)Item;
-(void)Pack;
-(void)Sort:(id<TListSortCompare>)Compare;
-(void)SetCapacity:(int)NewCapacity;
-(int)Capacity;
-(void)SetCount:(int)NewCount;
-(int)Count;
-(void*)Get:(int)Index;
-(void)Put:(int)Index:(void*)Item;
-(PPointerList)List;
-(void)Exchange:(int)Index1:(int)Index2;
//public function virtual
-(void)Clear;
@end

源文件:
//快速排序
void QuickSort(PPointerList List, int L, int R,
               id<TListSortCompare> SCompare)
{
    int i, j;
    void* p, *t;
    do {
        i = L;
        j = R;
        p = List[(L + R) >> 1];
        do{
            while([SCompare _Sort:List[i], p] < 0)
                ++i;
            while([SCompare _Sort:List[j], p] > 0)
                --j;
            if(i <= j)
            {
                t = List[i];
                List[i] = List[j];
                List[j] = t;
                ++i;
                --j;
            }
        }while(i < j);
        if(L < j)
            QuickSort(List, L, j, SCompare);
        L = i;
    }
    while(i <= R);
            
}


@implementation TList
-(void)dealloc
{
    [self Clear];
    [super dealloc];
};

-(void)Delete:(int)Index
{
    if((Index < 0)||(Index >= FCount))
       {
           raise(0);
           return;
       }
    void* temp = [self Get:Index];
    --FCount;
    if(Index < FCount)
        memcpy(&FList[Index], &FList[Index + 1], (FCount - Index) * sizeof(void*));
    if(temp)
        [self _Notify:temp :lnDeleted];
}

-(void)Exchange:(int)Index1 :(int)Index2
{
    if((Index1 < 0)||(Index1 >= FCount))
    {
        raise(0);
        return;
    }
    if((Index2 < 0)||(Index2 >= FCount))
    {
        raise(0);
        return;
    }
    void* item = FList[Index1];
    FList[Index1] = FList[Index2];
    FList[Index2] = item;
}

-(void*)Extract:(void *)Item
{
    void* res = nil;
    int i = [self IndexOf:Item];
    if(i >= 0)
    {
        res = Item;
        FList[i] = nil;
        [self Delete:i];
        [self _Notify:res :lnExtracted];
    }
    return res;
}

-(void)_Notify:(void *)P :(TListNotifyication)Action
{
    //nothing
}

-(int)Add:(void*)Item
{
    int res = FCount;
    if(res == FCapacity)
        [self _Grow];  
    memcpy(&FList[res], &Item, sizeof(void*));
    ++FCount;    
    if(Item)
        [self _Notify:Item:lnAdded];
    return res;
};

-(int)Capacity
{
    return FCapacity;
}

-(int)Count
{
    return FCount;
}

-(PPointerList)List
{
    return FList;
}

-(void)Clear
{
    [self SetCount:0];
    [self SetCapacity:0];
}
-(TList*)Expaned
{
  if(FCount == FCapacity)
      [self _Grow];
    return self;
}

-(void*)First
{
    return [self Get:0];
}

-(void*)Last
{
    return [self Get:FCount - 1];
}

-(void)Move:(int)CurIndex :(int)NewIndex
{
    if(CurIndex != NewIndex)
    {
        if((NewIndex < 0)||(NewIndex >= FCount))
            return;
        void* item = [self Get:CurIndex];
        FList[CurIndex] = nil;
        [self Delete:CurIndex];
        [self Insert:NewIndex :nil];
        FList[NewIndex] = item;
    }
}

-(void)Put:(int)Index :(void *)Item
{
    if((Index < 0)||(Index >= FCount))
    {
        raise(0);
        return;
    }
    if(Item != FList[Index])
    {
        void* temp = FList[Index];
        FList[Index] = Item;
        if(temp)
            [self _Notify:temp : lnDeleted];
        if(Item)
            [self _Notify:Item:lnAdded];
    }
}

-(int)Remove:(void *)Item
{
    int res = [self IndexOf:Item];
    if(res >= 0)
        [self Delete:res];
    return res;
}

-(void)Pack
{
    for(int i = FCount - 1; i >= 0; --i)
    {
        if([self Get:i] == nil)
            [self Delete:i];
    }
}

-(void)SetCapacity:(int)NewCapacity
{
    if((NewCapacity < FCount)||(NewCapacity > MaxListSize))
    {
        raise(0);
        return;
    }
    if(NewCapacity != FCapacity)
    {
        FList  = realloc(FList, NewCapacity * sizeof(void*));