File:  [Research Unix] / researchv10no / cmd / cfront / ptcfront / xBlock.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:35 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Norman

/*ident	"@(#)ctrans:src/Block.h	1.2" */

#ifndef BLOCK_H
#define BLOCK_H
#include <new.h>

PT_names
	Block(T)	Block_ T
PT_end

PT_define Blockdeclare(T)

class Block(T) {
public:
	unsigned size() const { return n; }
	unsigned size(unsigned);
	Block(T)() { n = 0; p = 0; }
	Block(T)(unsigned k) { n = 0; p = 0; size(k); }
	Block(T)(const Block(T)& b) { copy(b); }
	~Block(T)();
	Block(T)& operator=(const Block(T)&);
	operator T*() { return p; }
	operator const T*() const { return p; }
	T* end() { return p + n; }
	const T* end() const { return p + n; }
	T& operator[](int i) { return p[i]; }
	const T& operator[](int i) const { return p[i]; }
	int reserve(unsigned k) { return k<n || grow(k); }
	void swap(Block(T)& b);
private:
	T* p;
	unsigned n;
	void move(T*, unsigned);
	void transfer(T*, unsigned);
	void clear(T*, unsigned);
	void copy(const Block(T)&);
	unsigned grow(unsigned);
	static T* default_value();
};

PT_end

PT_define Blockimplement(T)

unsigned Block(T)::size(unsigned k)
{
	if (k != n)
		move(new T[k], k);
	return n;
}
Block(T)::~Block(T)()
{
	delete[] p;
}
Block(T)& Block(T)::operator=(const Block(T)& b)
{
	delete[] p;
	copy(b);
	return *this;
}

/* Clear k elements starting at v */
void
Block(T)::clear(T* v, unsigned k)
{
	register T* p = v;
	register T* lim = v + k;
	T* valptr = default_value();
	while (p < lim) {
		*p++ = *valptr;
	}
}

/* Make this a copy of b */
void
Block(T)::copy(const Block(T)& b)
{
	// assert (p is 0 or garbage)
	p = new T[b.n];
	if (p) {
		n = b.n;
		transfer(b.p, n);
	} else
		n = 0;
}

/* Grow this Block by 1.5 until it can contain at least k+1 */
unsigned
Block(T)::grow(unsigned k)
{
	unsigned nn = n;
	if (nn == 0)
		nn++;
	while (nn <= k)
		nn += (nn >> 1) + 1;
	T* np = new T[nn];
	if (!np) {
		nn = k+1;
		np = new T[nn];
	}
	move(np, nn);
	return n;
}

/* Transfer len (or fewer) elements into this Block. */
void
Block(T)::transfer(T* source, unsigned len)
{
	register T* plim;
	register T* pp = p;
	register T* q = source;

	if (n > len) {
		plim = p + len;
		clear(plim, n - len);
	} else
		plim = p + n;

	while (pp < plim)
		*pp++ = *q++;
}

/*
 * The contents of this Block now live in memory starting at np
 * If np is 0, null out this Block.
 */
void
Block(T)::move(T* np, unsigned nn)
{
	T* oldp = p;
	unsigned oldn = n;
	p = np;
	if (np) {
		n = nn;
		transfer(oldp, oldn);
	} else
		n = 0;
	delete[] oldp;
}

/* Exchange the contents of this Block with another Block */
void
Block(T)::swap(Block(T)& b)
{
	T* bp = b.p;
	unsigned bn = b.n;
	b.p = p;
	b.n = n;
	p = bp;
	n = bn;
}

T*
Block(T)::default_value() {
	static T default_item;
	return(&default_item);
}

PT_end


#endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.