俺様リスト.c

C言語むずい。
とりあえず、pushしたりpopしたりが手軽にできるリストを作ってみようと思ってがんばってみました。
elementをvoid*にすれば、intに限定せずいろんなデータ型で、と思ったんですがキャストしないとだめなのねー。
結局コピペしてOListChar_...ってのを作りました。 オーバーロードとかできればなぁ。


気付いたんだけどこれデータ構造的にはリストじゃないですね。 配列を触りやすくしたもの、ってな。

#ifndef _STDLIB_H
#define _STDLIB_H
#include <stdlib.h>
#endif

#ifndef _STDARG_H
#define _STDARG
#include <stdarg.h>
#endif

typedef struct{
    int*    element;
    int     i;
    int     size;
} OListInt;

OListInt*   OListInt_gen        ( int );
OListInt*   OListInt_new        ( int, ... );
OListInt*   OListInt_clone      ( OListInt**  );
OListInt*   OListInt_merge      ( OListInt**, OListInt**  );
void        OListInt_expand     ( OListInt**, int  );
void        OListInt_copy       ( OListInt**, OListInt**  );
void        OListInt_destroy    ( OListInt**  );
void        OListInt_free       ( OListInt**  );
void        OListInt_push       ( OListInt**, int  );
void        OListInt_unshift    ( OListInt**, int  );
int         OListInt_pop        ( OListInt** );
int         OListInt_shift      ( OListInt** );
void        OListInt_splice     ( OListInt**, int, int );
void        OListInt_exchange   ( OListInt**, int, int, OListInt** );
OListInt*   OListInt_slice      ( OListInt**, int, int );
OListInt*   OListInt_grep       ( OListInt**, int (*func)(int) );
#ifndef _OLIST_H
#define _OLIST_H
#include "olist.h"
#endif

/* OListInt */
OListInt* OListInt_gen( int size ){
    OListInt* this;
    this = (OListInt*)malloc(sizeof(int*) + sizeof(int) +sizeof(int));
    this->element = (int*)malloc(sizeof(int) * size);
    this->size    = size;
    this->i       = -1;
    return this;
}

OListInt* OListInt_new( int num, ... ){
    va_list args;
    OListInt* this;
    int i;
    
    va_start( args, num );
    
    this = OListInt_gen(num);
    
    for( i=0; i<=num-1; i++ )
        OListInt_push( &this, va_arg( args, int ) );
    
    va_end( args );
    
    return this;
}

void OListInt_expand( OListInt** this, int size ){
    OListInt* tmp;
    int i;
    
    tmp = OListInt_gen((*this)->size + size);
    OListInt_copy(this, &tmp);

    OListInt_free( this );
    *this = tmp;
}

void OListInt_copy( OListInt** this, OListInt** that ){
    int i;
    
    if( (*this)->i + 1 > (*that)->size )
        OListInt_expand( that, (*this)->size );
    
    for( i=0; i<=(*this)->i; i++ )
        OListInt_push(that, (*this)->element[i]);
}

OListInt* OListInt_clone( OListInt** this ){
    OListInt* clone;
    int i;
    
    clone = OListInt_gen((*this)->size);
    OListInt_copy( this, &clone );
    
    return clone;
}

void OListInt_destroy( OListInt** this ){
    free( (*this)->element );
    free( *this );
}

void OListInt_free( OListInt** this ){
    free( (*this)->element );
}

OListInt* OListInt_merge( OListInt** this, OListInt** that ){
    int i;
    OListInt* merged;
    
    merged = OListInt_gen((*this)->size+(*that)->size);
    

    OListInt_copy(this, &merged);    
    for(i=0; i<=(*that)->i; i++)
        OListInt_push(&merged, (*that)->element[i]);
    
    return merged;
}

void OListInt_push( OListInt** this, int that ){
    int i;
    
    if( (*this)->i + 1 >= (*this)->size )
        OListInt_expand(this, 1);
    
    (*this)->element[++(*this)->i] = that;
}

void OListInt_unshift( OListInt** this, int that ){
    OListInt* tmp;
    
    tmp = OListInt_new(1, that);
    *this = OListInt_merge(&tmp, this);
}

int OListInt_pop( OListInt** this ){
    return (*this)->element[(*this)->i--];    
}

int OListInt_shift( OListInt** this ){
    OListInt* tmp;
    int r;
    int i;
    tmp = OListInt_gen((*this)->size-1);
    
    r = (*this)->element[0];
    
    for(i=1; i<=(*this)->i; i++)
        OListInt_push(&tmp, (*this)->element[i]);
    
    *this = tmp;
    return r;
}

void OListInt_splice( OListInt** this, int offset, int len ){
    OListInt* tmp;
    int i;
    
    tmp = OListInt_new(0);
    for( i=0; i<=(*this)->i; i++ ){
        if( offset <= i && i<= offset + len-1)
            continue;
        OListInt_push( &tmp, (*this)->element[i]);
    }
    OListInt_free(this);
    *this = tmp;
}

void OListInt_exchange( OListInt** this, int offset, int len, OListInt** that ){
    OListInt* tmp;
    int i, j;
    
    tmp = OListInt_new(0);
    for( i=0; i<=(*this)->i; i++ ){
        if( i == offset )
            for( j=0; j<=(*that)->i; j++ )
                OListInt_push( &tmp, (*that)->element[j] );
        if( offset <= i && i<= offset + len-1)
            continue;
        OListInt_push( &tmp, (*this)->element[i] );
    }
    OListInt_free(this);
    *this = tmp;
}

OListInt* OListInt_slice( OListInt** this, int offset, int len ){
    OListInt* sliced;
    int i;
    
    sliced = OListInt_new(0);
    for( i=0; i<=(*this)->i; i++ ){
        if( offset <= i && i<= offset + len-1)
            OListInt_push( &sliced, (*this)->element[i]);
    }
    
    return sliced;
}

OListInt* OListInt_grep( OListInt** this, int(*c)(int) ){
    int i;
    OListInt* greped;
    
    greped = OListInt_new(0);
    for( i=0; i<=(*this)->i; i++ ){
        if( (*c)((*this)->element[i]) )
            OListInt_push( &greped, (*this)->element[i] );
    }
     
    return greped;   
}