www.pudn.com > ANSI_C_OOP.rar > List.dc


#include 

#ifndef	MIN
#define	MIN	32		// minimal buffer dimension
#endif

% List ctor {
	struct List * self = super_ctor(List, _self, app);

	if (! (self -> dim = va_arg(* app, unsigned)))
		self -> dim = MIN;
	self -> buf = malloc(self -> dim * sizeof * self -> buf);
	assert(self -> buf);
	return self;
}

% List dtor {
%casts
	free(self -> buf), self -> buf = 0;
	return super_dtor(List, self);
}

static void * add1 (struct List * self, const void * element)
{
	self -> end = self -> count = 1;
	return (void *) (self -> buf[self -> begin = 0] = element);
}

static void extend (struct List * self)	// one more element
{
	if (self -> count >= self -> dim)
	{	self -> buf =
				realloc(self -> buf, 2 * self -> dim
						* sizeof * self -> buf);
		assert(self -> buf);
		if (self -> begin && self -> begin != self -> dim)
		{	memcpy(self -> buf + self -> dim + self -> begin,
				self -> buf + self -> begin,
				(self -> dim - self -> begin)
						* sizeof * self -> buf);
			self -> begin += self -> dim;
		}
		else
			self -> begin = 0;
		self -> dim *= 2;
	}
	++ self -> count;
}

% List addFirst {
%casts
	if (! self -> count)
		return add1(self, element);
	extend(self);
	if (self -> begin == 0)
		self -> begin = self -> dim;
	self -> buf[-- self -> begin] = element;
	return (void *) element;
}

% List addLast {
%casts
	if (! self -> count)
		return add1(self, element);
	extend(self);
	if (self -> end >= self -> dim)
		self -> end = 0;
	self -> buf[self -> end ++] = element;
	return (void *) element;
}

% List count {
%casts
	return self -> count;
}

% List lookAt {
%casts
	return (void *) (n >= self -> count ? 0 :
		self -> buf[(self -> begin + n) % self -> dim]);
}

% List takeFirst {
%casts
	if (! self -> count)
		return 0;
	-- self -> count;
	if (self -> begin >= self -> dim)
		self -> begin = 0;
	return (void *) self -> buf[self -> begin ++];
}

% List takeLast {
%casts
	if (! self -> count)
		return 0;
	-- self -> count;
	if (self -> end == 0)
		self -> end = self -> dim;
	return (void *) self -> buf[-- self -> end];
}

%init