seq.c
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:3k
- static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/seq.doc,v 1.11 1997/02/21 19:48:24 drh Exp $";
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include "assert.h"
- #include "seq.h"
- #include "array.h"
- #include "arrayrep.h"
- #include "mem.h"
- #define T Seq_T
- struct T {
- struct Array_T array;
- int length;
- int head;
- };
- static void expand(T seq) {
- int n = seq->array.length;
- Array_resize(&seq->array, 2*n);
- if (seq->head > 0)
- {
- void **old = &((void **)seq->array.array)[seq->head];
- memcpy(old+n, old, (n - seq->head)*sizeof (void *));
- seq->head += n;
- }
- }
- T Seq_new(int hint) {
- T seq;
- assert(hint >= 0);
- NEW0(seq);
- if (hint == 0)
- hint = 16;
- ArrayRep_init(&seq->array, hint, sizeof (void *),
- ALLOC(hint*sizeof (void *)));
- return seq;
- }
- T Seq_seq(void *x, ...) {
- va_list ap;
- T seq = Seq_new(0);
- va_start(ap, x);
- for ( ; x; x = va_arg(ap, void *))
- Seq_addhi(seq, x);
- va_end(ap);
- return seq;
- }
- void Seq_free(T *seq) {
- assert(seq && *seq);
- assert((void *)*seq == (void *)&(*seq)->array);
- Array_free((Array_T *)seq);
- }
- int Seq_length(T seq) {
- assert(seq);
- return seq->length;
- }
- void *Seq_get(T seq, int i) {
- assert(seq);
- assert(i >= 0 && i < seq->length);
- return ((void **)seq->array.array)[
- (seq->head + i)%seq->array.length];
- }
- void *Seq_put(T seq, int i, void *x) {
- void *prev;
- assert(seq);
- assert(i >= 0 && i < seq->length);
- prev = ((void **)seq->array.array)[
- (seq->head + i)%seq->array.length];
- ((void **)seq->array.array)[
- (seq->head + i)%seq->array.length] = x;
- return prev;
- }
- void *Seq_remhi(T seq) {
- int i;
- assert(seq);
- assert(seq->length > 0);
- i = --seq->length;
- return ((void **)seq->array.array)[
- (seq->head + i)%seq->array.length];
- }
- void *Seq_remlo(T seq) {
- int i = 0;
- void *x;
- assert(seq);
- assert(seq->length > 0);
- x = ((void **)seq->array.array)[
- (seq->head + i)%seq->array.length];
- seq->head = (seq->head + 1)%seq->array.length;
- --seq->length;
- return x;
- }
- void *Seq_addhi(T seq, void *x) {
- int i;
- assert(seq);
- if (seq->length == seq->array.length)
- expand(seq);
- i = seq->length++;
- return ((void **)seq->array.array)[
- (seq->head + i)%seq->array.length] = x;
- }
- void *Seq_addlo(T seq, void *x) {
- int i = 0;
- assert(seq);
- if (seq->length == seq->array.length)
- expand(seq);
- if (--seq->head < 0)
- seq->head = seq->array.length - 1;
- seq->length++;
- return ((void **)seq->array.array)[
- (seq->head + i)%seq->array.length] = x;
- }