home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
progjour
/
1990
/
05
/
vint.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-06
|
7KB
|
189 lines
#ifdef __TURBOC__
#include <stdio.h>
#include <iostream.h>
#else
#include <stream.hpp>
#endif
#include <stdlib.h>
#include "virt.hpp"
// VINT.CPP: Example of how to encapsulate the virtual memory functions in
//virt.c into a C++ object. #include this file to get support for virtual
//int arrays. Compile with COMPILE_METHODS defined to create library-
//support functions. Define MAIN to get a small test program.
// Declarations:
// vint x(100L); Create a virtual array of 100 ints
// Valid operations:
// x[n] This is a selector operator. The next operation
// controls what happens to that element. The
// following operations are supported (x is a vint
// and i is an int):
// i + x[n] i - x[n] i * x[n] i / x[n] i = x[n]
// x[n] + i x[n] - i x[n] * i x[n] / i x[n] = i
// x[n] + x[i] x[n] - x[i] x[n] * x[i] x[n] / x[i] x[n] = x[i]
// ++x[n] --x[n]
// All of these operators evaluate to int rvalues, so
// (x[i] = x[j] = x[k]) doesn't work.
// x[n] by itself evaluates to a reference to a vint, not to an int. There
// is a vint-to-int conversion supplied so that you can use a reference
// directly, however.
// Something like x+i, with no index on the x, uses the most-recently-
// selected element. This syntax is weird--it's really a side effect of
// the select-then-operate strategy--so you shouldn't use it.
// Finally, note that an long-to-vint conversion is supplied by because of
// the constructor syntax. This conversion doesn't do what you think (it
// creates an empty array of the size specified in the conversion).
// Be careful.
class vint {
private:
static int nobj; // number of active objects
void *hdr; // virtual-memory handle
int *cur_ele; // Most recently selected object.
long cur_index; // index of "
friend int val( vint &v );
public:
vint ( long array_size );
~vint ();
vint ( vint &hdr );
operator int ();
vint &operator [] ( long index );
int operator + ( /* this, */ int i );
int operator - ( /* this, */ int i );
int operator * ( /* this, */ int i );
int operator / ( /* this, */ int i );
int operator = ( /* this, */ int i );
int operator = ( /* this, */ vint &v );
int operator ++ ( /* this, */ );
int operator -- ( /* this, */ );
friend int operator + ( int i, vint &r );
friend int operator - ( int i, vint &r );
friend int operator * ( int i, vint &r );
friend int operator / ( int i, vint &r );
friend int operator + ( vint &l, vint &r );
friend int operator - ( vint &l, vint &r );
friend int operator * ( vint &l, vint &r );
friend int operator / ( vint &l, vint &r );
};
#ifdef COMPILE_METHODS
//constructor, starts up the virtual-memory system the first time it's
//called. Allocates a new array.
vint::vint( long array_size ) : cur_ele(NULL), cur_index(0) {
if ( nobj++ == 0 )
vopen(); // initialize the virtual-memory system
if ( !(hdr = vmalloc(array_size, sizeof(int))) ) {
perror( "VMS allocation error" );
exit( 1 );
}
}
vint::~vint() { // destructor, frees current object and if no more objects
if ( !vfree( hdr ) ) { // are left, shuts down virtual-memory system
perror( "VMS deallocation error" );
exit( 1 );
}
if ( --nobj == 0 )
vclose(); // close down the virtual-memory system
}
vint::vint( vint &src ) : cur_ele(NULL), cur_index(0) {
// Copy constructor. VERY expensive operation. duplicates array in src.
int *p;
long numele = vele( src.hdr );
if ( nobj++ == 0 )
vopen(); // initialize the virtual-memory system
if ( hdr && !vfree( hdr ) ) {
perror( "VMS copy-deallocation error" );
exit( 1 );
}
if ( !(hdr = vmalloc( numele, sizeof(int))) ) {
perror( "VMS copy-allocation error" );
exit( 1 );
}
while ( --numele >= 0 ) {
if ( !(p = (int *)vread( src.hdr, numele )) ) {
perror ( "VMS copy-access (read) error." );
exit( 1 );
}
if ( !vwrite( hdr, numele, p ) ) {
perror( "VMS copy-access (write) error.\n" );
exit( 1 );
}
}
}
vint::operator int()
{ // convert vint to int
if ( cur_ele )
return *cur_ele;
cerr << "VMS: no previous index on vint.\n";
return 0;
}
vint &vint::operator []( long index ) { // select an array member
if ( !(cur_ele = (int *)vread( hdr, index )) )
perror( "VMS selection error" );
cur_index = index;
return *this;
}
// The following methods all modify the member that was selected by a
// previous array-index ([i]) operator. Note that there's no provision for
// a vint=vint operator because the earlier vint-to-int conversion will act
// on the right argument to make it suitable for the vint=int operator
// defined below.
/* static */ int val( vint &v ) { // return the value of the currently-
if ( v.cur_ele ) // selected member.
return *v.cur_ele ;
cerr << "VMS: No previous index on vint (val)\n" ;
return 0;
}
int vint::operator ++ () { // increment the current member
val(*this); // val call for error checking.
vdirty(hdr);
return ++*cur_ele;
}
int vint::operator -- () { // decrement the current member
val(*this); // val call for error checking.
vdirty(hdr);
return --*cur_ele;
}
int vint::operator = ( int i ) { // assign to the current member
if ( !cur_ele ) {
cerr << "VMS: No array index on a vint (=)\n" ;
return 0;
}
vdirty( hdr );
return *cur_ele = i;
}
#endif /* COMPILE_METHODS */
// These functions take care of the nondestructive arithmetic
// operations. The ones with two arguments are friends of class vint.
inline int vint::operator + ( int i ){ return val(*this) + i; }
inline int vint::operator - ( int i ){ return val(*this) - i; }
inline int vint::operator * ( int i ){ return val(*this) * i; }
inline int vint::operator / ( int i ){ return val(*this) / i; }
inline int operator + (int i, vint &r){ return i + val(r); }
inline int operator - (int i, vint &r){ return i - val(r); }
inline int operator * (int i, vint &r){ return i * val(r); }
inline int operator / (int i, vint &r){ return i / val(r); }
inline int operator + (vint &l, vint &r){ return val(l) + val(r); }
inline int operator - (vint &l, vint &r){ return val(l) - val(r); }
inline int operator * (vint &l, vint &r){ return val(l) * val(r); }
inline int operator / (vint &l, vint &r){ return val(l) / val(r); }