Category : C++ Source Code
Archive   : WHEATLIB.ZIP
Filename : OBJVEC.H
#define ObjVecIncluded
// copyright (c) 1992 by Paul Wheaton
// 1916 Brooks #205, Missoula, MT 59801
//
// voice phone: (406)543-7543
// modem phone: (406)543-1144 (2400N81)
// CompuServe: 72707,207
// Internet: [email protected]
#include
/*
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.
*/
class ObjVec: private ByteVector
{
Word ObjSize; // size of struct or atomic object: 2 if int, 4 if long, etc.
Word BlockSize; // see "BlockSize" at bottom of file
void CtorHelper(Word);
public:
ObjVec(Word ObjectSize);
ObjVec(Word ObjectSize,void*);
ObjVec(Word ObjectSize,void*,void*);
ObjVec(Word ObjectSize,void*,void*,void*);
ObjVec(Word ObjectSize,void* P, Long Len); // copy from some pointer
ObjVec(const ObjVec&);
void ExtraAlloc(Long Quan);
void* Ref(Long Index); // returns pointer to that element
operator ConstVoidPointerType(); //{return P;}
void CopyTo(void* Dest, Long Quan=MaxLong); // copy from vector to memory
void CopyFrom(void* Source, Long Quan); // copy to vector from memory
void WriteTo(File&); // write a ObjVec object to file
Long Capacity(); // {return (Alloc/ObjSize);}
Long ByteCapacity();
Long ReAlloc(Long NewCapacity);
Long Size(); // {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); }
void operator+=(const ObjVec&);
ObjVec Concat(const ObjVec&);
ObjVec Concat(void*);
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 Clear(Word X=0); // set all elements to X
Long Sum();
void Empty(); //{Len=0;}
Long Index(void* SearchObj, Long StartIndex);
ObjVec At(Long,Long);
void* At(Long);
ObjVec From(Long index);
ObjVec After(Long index);
};
#define CreateAtomicVectorClass(ClassName,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);} \
void operator+=(ObjType X){AppendOneObj(&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) \
{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);} \
};
#define CreateRefVectorClass(ClassName,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);} \
void operator+=(ObjType& X){AppendOneObj(&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);} \
};
#endif
/*
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).
*/
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
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/