Category : C++ Source Code
Archive   : WLIB.ZIP
Filename : WVEC.H

 
Output of file : WVEC.H contained in archive : WLIB.ZIP
#ifndef WVecIncluded
#define WVecIncluded

// copyright (c) 1992, 1993 by Paul Wheaton, Banana Programming
// 1916 Brooks #205, Missoula, MT 59801
//
// phone: (406)543-1928
// CompuServe: 72707,207
// Internet: [email protected]
// BBS: (406)543-8234 (The Montana Banana BBS)

/* things to add
lower bounds (in an inherited class)
Minimize() member function to make Alloc==Len
virtual memory handler (using disk)
*/

#include
#include

class File;

typedef const void* ConstVoidPointerType; // xxx used to clear up cfront prob

class ByteVector
{
Byte huge* P; // pointer to first Byte in storage
long Len; // Length of vector
long Alloc; // amount of actual storage allocated
long Extra; // amount of extra memory to allocate when getting more memory
void ReNew(long NewCapacity);
Byte huge & Ref(long Index);
friend class BitVector;
void Assign(const ByteVector& BV);
void FreeMemory(); // equivalent to new or delete
Byte Selectors(); // 16M only: number of selectors used. 0 if using malloc
friend void DebugDisp(const ByteVector& BV);
friend class File;
friend class RecFile;
friend class ObjVec;
public:
ByteVector();
ByteVector(int); // although these say "int", they'll be
ByteVector(int,int); // converted to Bytes. "int" makes for shorter
ByteVector(int,int,int); // mangled identifiers than "Byte"
ByteVector(int,int,int,int);
ByteVector(int,int,int,int,int);
ByteVector(int,int,int,int,int,int);
ByteVector(int,int,int,int,int,int,int);
ByteVector(int,int,int,int,int,int,int,int);
ByteVector(int,int,int,int,int,int,int,int,int);
// see the notes on the constructors at the end of this file
ByteVector(void* B, long Len); // copy from some pointer
ByteVector(const ByteVector&);
ByteVector(File& F); // read a ByteVector object from a file
~ByteVector(){FreeMemory();}
void ExtraAlloc(long Quan){Extra=Quan;}
// each time more memory is needed, this is how much extra is allocated
Byte huge & operator[](long Index){return Ref(Index);}
// To access and modify specific bytes of the vector.
// Accessing beyond the current length will increase the vector size.
// Completely range protected.
void operator=(const ByteVector& BV) {Assign(BV);}
Bool operator==(const ByteVector& S);
Bool operator!=(const ByteVector& S) { return !(*this==S); }
// vector concatenation
ByteVector operator+(const ByteVector& B);
ByteVector operator+(Byte B);
friend ByteVector operator+(Byte B, const ByteVector& BV);
void operator+=(const ByteVector&);
void operator+=(Byte B) {Ref(Len)=B;}
operator ConstVoidPointerType(){return P;}
void CopyTo(void* Dest, long Bytes=MaxSLong); // copy from vector to memory
void CopyFrom(void* Source, long Bytes); // copy from memory to vector
//friend void operator=(void* Dest,const ByteVector& BV) {BV.CopyTo(Dest);}
void WriteTo(File& F); // write a ByteVector object to file
long Capacity() {return Alloc;}
long ReAlloc(long NewCapacity);
void MinimizeMemory();
// reduce memory consumption to just what is needed now
long Size() {return Len;}
long Index(Byte SearchByte, long StartIndex=0);
// returns the const NotFound if the Byte is not found in the vector
// otherwise returns the index

Byte operator()(long Index); // return an indexed byte.
ByteVector operator()(long Index, long Length); // return a subvector
Byte At(long I);
ByteVector At(long Index, long Length);
ByteVector Before(long Index) {return At(0,Index);}
ByteVector Through(long Index) {return At(0,Index+1);}
ByteVector From(long Index);
ByteVector After(long Index);
void Insert(Byte C,long Index=0);
void Insert(const ByteVector& BV,long Index=0);
void Delete(long Index=0,long Length=1);
void Clear(Byte B=0); // set all elements to B
void ClearFirst(long Quan) {Ref(Quan); Clear();}
// great for initializing a vector
long Sum();
void Empty(){Len=0;}
void Clip(long NewSize);
#ifdef MAJORBBS
void* operator new(size_t size){return malloc(size);}
void operator delete(void* p) {free(p);}
#endif
};

extern Bool BigVectorJump;
/* If true, then vectors in size >64k will always be allocated in chunks of
64k. This saves on fragmentation and recopying time. Default is True. */

const DefaultVectorExtra=16;

/*

ByteVector constructors:

I wanted to use a variable argument constructor (see your favorite texts
on "elipsis", "...", "variable arguments" or "va_arg, va_end and
va_start") but there were limitations that I felt could lead to very hard
to find bugs, namely that the applications programmer must first pass a
value that reveals how many parameters there are. Being off by one could
lead to a variety of problems.

There are four ways to construct a ByteVector:

1) ByteVector BV;

This creates a vector that will have a length of 0 although some
memory will be allocated so that elements may be added later (which
is the most likely thing to happen).

2) ByteVector BV(1,2,55,8);

This creates a vector of length 4. You may pass 1 to 9 parameters
using this type of constructors. You're limited to 9 because the
Glock C++ name mangling mixed with MSC 5.1 limits it this way. An
update of either of these may solve this problem.

3) static Byte BA[]={1,2,55,8};
ByteVector BV(BA,4);

This creates a vector of length 4, copying the elements from BA.
You don't have to copy from an array of bytes, you can use any kind
of array or even a pointer to anywhere in memory.

4) ByteVector BV2(BV);

Create a ByteVector from another ByteVector.

*/

/*

Note that I use the word "Atomic" in the context that it's used in the
LISP language, meaning language primitives such as int, long and float.

The classes that are derived from ObjVec using the macros
"CreateAtomicVectorClass" or "CreateRefVectorClass"are for those types of
objects that do not need any special class constructors or destructors.
The former macro passes values through the stack as much as possible.
The latter passes pointers (as references). They should both appear to
work the same way although there may be some differences in time and
space usage depending on your object size and how you use your vectors.

Again, do not use objects in these vectors that cannot be bit copied,
such as class objects that contain pointers that require stack
maintenance.

*/

typedef int (* CompFuncPtr)(const void*,const void*);

class ObjVec: private ByteVector
{
int ObjSize; // size of struct or atomic object: 2 if int, 4 if long, etc.
int BlockSize; // see "BlockSize" at bottom of file
CompFuncPtr CFP;
void CtorHelper(int);
CompFuncPtr CurCompFunc() const;
public:
ObjVec(int ObjectSize);
ObjVec(int ObjectSize,void*);
ObjVec(int ObjectSize,void*,void*);
ObjVec(int ObjectSize,void*,void*,void*);
ObjVec(int ObjectSize,void* P, long Len); // copy from some pointer
ObjVec(const ObjVec&);

void ExtraAlloc(long Quan);
// when more memory is needed, how much more memory should be allocated?
void* Ref(long Index); // returns pointer to that element
operator ConstVoidPointerType() const; //{return P;}
void CopyTo(void* Dest, long Quan=MaxSLong) const; // copy from vector to memory
void CopyFrom(void* Source, long Quan); // copy to vector from memory
void WriteTo(File&) const; // write a ObjVec object to file
long Capacity() const; // {return (Alloc/ObjSize);}
long ByteCapacity() const;
long ReAlloc(long NewCapacity);
long Size() const; // {return Len/ObjSize);}
//friend void operator=(void* Dest,const ObjVec& V);
void operator=(const ObjVec& V);// {Assign(V);}
//Bool operator==(ObjVec&);
//Bool operator!=(ObjVec& V);// { return !(*this==V); }
long Index(void* SearchObj, long StartIndex) const;
void operator+=(const ObjVec&);
ObjVec Concat(const ObjVec&) const;
ObjVec Concat(void*) const;
void AppendOneObj(void*);
ObjVec PrependOneObj(void*) const; // does not modify current obj
void Insert(const ObjVec& V,long Index=0);
void Insert(void*,long Index);
void Delete(long Index=0,long Length=1);
void Pop(){Delete(Size()-1,1);}
//void Clear(int X=0); // set all elements to X
void ClearFirst(long Quan) {Ref(Quan); Clear();}
// great for initializing a vector
long Sum() const;
void Empty(); //{Len=0;}
ObjVec At(long,long) const;
void* At(long) const;
ObjVec From(long index) const;
ObjVec After(long index) const;
void Clip(long NewSize){ByteVector::Clip(NewSize*BlockSize);}

void SetCompFunction(void* F){CFP=(CompFuncPtr)F;}
// in BInsert(), FindE(), FindGE() and QSort() this function will be
// used in the binary search. Otherwise, int or long comps will be done
long BInsert(void* X);
// does a binary search and then inserts X. returns index num. if a
// dupe is found, nothing is inserted and the match index is returned.
long FindE(void* SearchObj) const;
// binary search. returns index. returns NotFound if no exact match
long FindGE(void* SearchObj) const;
// returns NotFound if SearchObj is greater than last element
void QSort();
// note that the sort will be limited by the limitations that come with
// the ANSI QSort

#ifdef MAJORBBS
void* operator new(size_t size){return malloc(size);}
void operator delete(void* p) {free(p);}
#endif
};

#define CreateAtomicVectorClass(ClassName,ObjType) \
typedef int (* ObjType ## CompFuncPtr)(const ObjType*,const ObjType*); \
class ClassName:public ObjVec \
{ \
public: \
ClassName():ObjVec(sizeof(ObjType)){} \
ClassName(ObjType X):ObjVec(sizeof(ObjType),&X){} \
ClassName(ObjType X1, ObjType X2):ObjVec(sizeof(ObjType),&X1,&X2){} \
ClassName(ObjType X1, ObjType X2, ObjType X3) \
:ObjVec(sizeof(ObjType),&X1,&X2,&X3){} \
ClassName(void* P, long Len):ObjVec(sizeof(ObjType),P,Len){} \
ClassName(const ClassName& V):ObjVec(V){} \
ClassName(const ObjVec& V):ObjVec(V){} \
ObjType& Ref(long Index) {return *(ObjType*)ObjVec::Ref(Index);} \
ObjType& operator[](long Index){return *(ObjType*)ObjVec::Ref(Index);} \
ObjType& Last(){return Ref(Size()-1);} \
void operator+=(ObjType X){AppendOneObj(&X);} \
void operator+=(ClassName X){ObjVec::operator+=(X);} \
ClassName operator+(const ClassName& V){return ObjVec::Concat(V);} \
ClassName operator+(ObjType X){return ObjVec::Concat(&X);} \
friend ClassName operator+(ObjType X, const ClassName& V1) \
{return V1.PrependOneObj(&X);} \
long Index(ObjType SearchObj, long StartIndex=0) const \
{return ObjVec::Index(&SearchObj,StartIndex);} \
ObjType operator()(long Index) const \
{return *(ObjType*)ObjVec::At(Index);} \
ClassName operator()(long Index, long Length) const \
{return ObjVec::At(Index,Length);} \
ObjType At(long Index){return *(ObjType*)ObjVec::At(Index);} \
ClassName At(long Index, long Length) \
{return ObjVec::At(Index,Length);} \
ClassName Before(long Index){return ObjVec::At(0,Index);} \
ClassName Through(long Index){return ObjVec::At(0,Index+1);} \
ClassName From(long Index){return ObjVec::From(Index);} \
ClassName After(long Index){return ObjVec::After(Index);} \
void Insert(ObjType C,long Index=0){ObjVec::Insert(&C,Index);} \
void SetCompFunction(ObjType ## CompFuncPtr CFP) \
{ObjVec::SetCompFunction((void*)CFP);} \
long BInsert(ObjType X){return ObjVec::BInsert(&X);} \
long FindE(ObjType X){return ObjVec::FindE(&X);} \
long FindGE(ObjType X){return ObjVec::FindGE(&X);} \
};

#define CreateRefVectorClass(ClassName,ObjType) \
typedef int (* ObjType ## CompFuncPtr)(const ObjType*,const ObjType*); \
class ClassName:public ObjVec \
{ \
public: \
ClassName():ObjVec(sizeof(ObjType)){} \
ClassName(ObjType& X):ObjVec(sizeof(ObjType),&X){} \
ClassName(ObjType& X1, ObjType& X2): \
ObjVec(sizeof(ObjType),&X1,&X2){} \
ClassName(ObjType& X1, ObjType& X2, ObjType& X3) \
:ObjVec(sizeof(ObjType),&X1,&X2,&X3){} \
ClassName(void* P, long Len):ObjVec(sizeof(ObjType),P,Len){} \
ClassName(const ClassName& V):ObjVec(V){} \
ClassName(const ObjVec& V):ObjVec(V){} \
ObjType& Ref(long Index) {return *(ObjType*)ObjVec::Ref(Index);} \
ObjType& operator[](long Index){return Ref(Index);} \
ObjType& Last(){return Ref(Size()-1);} \
void operator+=(ObjType& X){AppendOneObj(&X);} \
void operator+=(ClassName X){ObjVec::operator+=(X);} \
ClassName operator+(const ClassName& V){return Concat(V);} \
ClassName operator+(ObjType& X){return Concat(&X);} \
friend ClassName operator+(ObjType& X, const ClassName& V1) \
{return V1.PrependOneObj(&X);} \
long Index(ObjType& SearchObj, long StartIndex=0) \
{return ObjVec::Index(&SearchObj,StartIndex);} \
ObjType operator()(long Index) {return *(ObjType*)ObjVec::At(Index);} \
ClassName operator()(long Index, long Length) \
{return ObjVec::At(Index,Length);} \
ObjType At(long Index){return *(ObjType*)ObjVec::At(Index);} \
ClassName At(long Index, long Length) \
{return ObjVec::At(Index,Length);} \
ClassName Before(long Index){return ObjVec::At(0,Index);} \
ClassName Through(long Index){return ObjVec::At(0,Index+1);} \
ClassName From(long Index){return ObjVec::From(Index);} \
ClassName After(long Index){return ObjVec::After(Index);} \
void Insert(ObjType& C,long Index=0){ObjVec::Insert(&C,Index);} \
void SetCompFunction(ObjType ## CompFuncPtr CFP) \
{ObjVec::SetCompFunction((void*)CFP);} \
long BInsert(ObjType& X){return ObjVec::BInsert(&X);} \
long FindE(ObjType& X){return ObjVec::FindE(&X);} \
long FindGE(ObjType& X){return ObjVec::FindGE(&X);} \
};

/*

BlockSize

In protected mode (16M uses this) when using large chunks of memory
(beyond 64K), that represent an array of objects, the objects must occupy
a space that has a size that is a power of two (1, 2, 4, 8, 16, etc.).
This is so that a long will not lie on a 64k boundry and assignments will
be done to it (memory is not contiguous but, rather, in 64k chunks
managed by a table of contiguous pointers).


*/

CreateAtomicVectorClass(IntVector,int);
CreateAtomicVectorClass(LongVector,long);
CreateAtomicVectorClass(CSVector,CharStar);

#endif



  3 Responses to “Category : C++ Source Code
Archive   : WLIB.ZIP
Filename : WVEC.H

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/