/*ident "@(#)Block:incl/Block.c 3.1" */ /****************************************************************************** * * C++ Standard Components, Release 3.0. * * Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc. * Copyright (c) 1988, 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. * ******************************************************************************/ #ifdef __GNUG__ #pragma implementation "Block.h" #endif #include #include #ifdef __GNUG__ template class Block; #endif #ifndef __GNUG__ // This exists to cut the instantiation dimension from 5 to 2 // by "calling" all the functions that are used for any Block. void Block::dummy_fcn() { Block foo; foo.size(0); foo.move(0,0); foo.transfer(0,0); foo.clear(0,0); foo.copy(foo); foo.grow(0); (void)default_value(); } unsigned Block::size(unsigned k) { if ( k != n ) // Move, even when shrinking, since move(new TYPE[k], k); // the unused space can't be reused return n; } Block::~Block() { if (p) delete[] p; } Block& Block::operator=(const Block& b) { if ( this != &b ) { if (p) delete[] p; copy(b); } return *this; } // Clear k elements starting at v void Block::clear(TYPE* v, unsigned k) { register TYPE* _p = v; register TYPE* lim = v + k; TYPE* valptr = default_value(); while ( _p < lim ) *_p++ = *valptr; } // Make this a copy of b void Block::copy(const Block& b) { // assert (p is 0 or garbage) p = new TYPE[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::grow(unsigned k) { unsigned nn = n; if ( nn == 0 ) nn++; while ( nn <= k ) nn += (nn >> 1) + 1; TYPE* np = new TYPE[nn]; if ( !np ) { nn = k+1; np = new TYPE[nn]; } move(np, nn); // takes care of case when np == 0 return n; } // Transfer len (or fewer) elements into this Block. void Block::transfer(TYPE* source, unsigned len) { register TYPE* plim; register TYPE* pp = p; register TYPE* 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::move(TYPE* np, unsigned nn) { TYPE* oldp = p; unsigned oldn = n; p = np; if ( np ) { n = nn; transfer(oldp, oldn); } else n = 0; if (oldp) delete[] oldp; } // Exchange the contents of this Block with another Block void Block::swap(Block& b) { TYPE* bp = b.p; unsigned bn = b.n; b.p = p; b.n = n; p = bp; n = bn; } TYPE* Block::default_value() { static TYPE default_item; return(&default_item); } #endif