Personal tools
You are here: Home Projects C++ Cfront releases Release 3.0.3 source lib new #5fvec.c
Document Actions

#5fvec.c

by Michael L Powell last modified 2007-01-26 03:21

Click here to get the file

Size 3.2 kB - File type text/plain

File contents

/*ident	"@(#)cls4:lib/new/_vec.c	1.5" */
/*******************************************************************************
 
C++ source for the C++ Language System, Release 3.0.  This product
is a new release of the original cfront developed in the computer
science research center of AT&T Bell Laboratories.

Copyright (c) 1993  UNIX System Laboratories, Inc.
Copyright (c) 1991, 1992 AT&T and UNIX System Laboratories, Inc.
Copyright (c) 1984, 1989, 1990 AT&T.  All Rights Reserved.

THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX System
Laboratories, Inc.  The copyright notice above does not evidence
any actual or intended publication of such source code.

*******************************************************************************/



typedef void* PV;
typedef void (*PF)(PV,int,int,int,int,int,int,int,int);
typedef void (*PFI)(PV,int ...);
/*
	ERROR: cannot handle classes with more than 8 virtual bases
*/

// functions that manage the map from arrays to their element counts
extern int	__insert_new_array(PV key, int count);
	// key is a pointer to a new array.  It must
	//	be non-zero
	//	not already be in the table
	// count is the number of elements in the array.  May be zero
extern int	__remove_old_array(PV key);
	// removes an old array from the table.  Returns the count or -1 if not found

static PV	__cache_key;
static int	__cache_count;

#ifdef __cplusplus
extern "C"
#endif

PV __vec_new(PV op, int n, int sz, PV f)
/*
	allocate a vector of "n" elements of size "sz"
	and initialize each by a call of "f"
	op is zero when operator new(size_t) (which may have been
		supplied by the user) is to be used to allocate storage,
		i.e., for  new T[n]
	op is non-zero when another operator new() has already been used
		to allocate storage, i.e.,  new (<args>) T[n]
		or when the array is static/extern or automatic
*/
{
	int es;
	int opf = (op == 0);

	if (op == 0) // allocate storage if not already done
		op = PV( new char[n*sz] );  // this is the global operator new

	if (op) {  // put (array, count) into the cache
		es = 0;
		if (__cache_key)
			es = __insert_new_array(__cache_key, __cache_count);
		if (es == -1) {
			if (opf)
				delete op;
			return 0;
		}
		__cache_key = op;
		__cache_count = n;
	}

	if (op && f) {
		register char* p = (char*) op;
		register char* lim = p + n*sz;
		register PF fp = PF(f);
		while (p < lim) {
			(*fp) (PV(p),0,0,0,0,0,0,0,0);
			p += sz;
		}
	}
	return PV(op);
}

#ifdef __cplusplus
extern "C"
#endif
void __vec_delete(PV op, int n, int sz, PV f, int del, int)
/*
	clean up a vector at op and optionally delete it
	del is nonzero if the vector is to be deleted, i.e., delete [] p
	del is zero if the vector is on the stack or static
	n is the size if given or the vector is automatic or static
	n is -1 if the vector is dynamic, i.e., delete [] p
	sz is sizeof(T)
	f is the destructor
*/
{
	if (op) {
		int	ans = __cache_key == op ?
			((__cache_key = 0), __cache_count) :
			__remove_old_array(op); // -1 if not found
		if (n == -1) n = ans;  // prefer given size
		if (f) {
			register char* cp = (char*) op;
			register char* p = cp;
			register PFI fp = PFI(f);
			p += n*sz;
			while (p > cp) {
				p -= sz;
				(*fp)(PV(p), 2);  // destroy VBC, don't delete
			}
		}
		if (del) delete op;
	}
}


« August 2014 »
Su Mo Tu We Th Fr Sa
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: