home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / c / WLIB.ZIP / WVEC.H < prev   
Encoding:
C/C++ Source or Header  |  1993-04-05  |  15.1 KB  |  320 lines

  1. #ifndef WVecIncluded
  2. #define WVecIncluded
  3.  
  4. // copyright (c) 1992, 1993 by Paul Wheaton
  5. // 1916 Brooks #205, Missoula, MT  59801
  6. //
  7. // voice phone:  (406)543-7543
  8. // modem phone:  (406)543-1144 (2400N81)
  9. //  CompuServe:  72707,207
  10. //    Internet:  72707.207@CompuServe.com
  11.  
  12. /* things to add
  13.      lower bounds (in an inherited class)
  14.      Minimize() member function to make Alloc==Len
  15.      virtual memory handler (using disk)
  16.      ExtraAlloc() mem func to set how much extra is to be allocated each
  17.        time more memory is allocated (this will speed up rapidly growing
  18.        vectors)
  19.      vector sizes beyond 64k
  20. */
  21.  
  22. #include <WMisc.h>
  23.  
  24. #ifdef MAJORBBS
  25.   #include <stdlib.h>
  26. #endif
  27.  
  28. class File;
  29.  
  30. typedef const void* ConstVoidPointerType;  // xxx used to clear up cfront prob
  31.  
  32. class ByteVector
  33.   {
  34.       Byte huge* P; // pointer to first Byte in storage
  35.       long Len;   // Length of vector
  36.       long Alloc; // amount of actual storage allocated
  37.       long Extra; // amount of extra memory to allocate when getting more memory
  38.       void ReNew(long NewCapacity);
  39.       Byte huge & Ref(long Index);
  40.       friend class BitVector;
  41.       void Assign(const ByteVector& BV);
  42.       void FreeMemory();  // equivalent to new or delete
  43.       Byte Selectors(); // 16M only:  number of selectors used.  0 if using malloc
  44.       friend void DebugDisp(const ByteVector& BV);
  45.       friend class File;
  46.       friend class RecFile;
  47.       friend class ObjVec;
  48.     public:
  49.       ByteVector();
  50.       ByteVector(int);          // although these say "int", they'll be
  51.       ByteVector(int,int);      // converted to Bytes.  "int" makes for shorter
  52.       ByteVector(int,int,int);  // mangled identifiers than "Byte"
  53.       ByteVector(int,int,int,int);
  54.       ByteVector(int,int,int,int,int);
  55.       ByteVector(int,int,int,int,int,int);
  56.       ByteVector(int,int,int,int,int,int,int);
  57.       ByteVector(int,int,int,int,int,int,int,int);
  58.       ByteVector(int,int,int,int,int,int,int,int,int);
  59.       //  see the notes on the constructors at the end of this file
  60.       ByteVector(void* B, long Len);  // copy from some pointer
  61.       ByteVector(const ByteVector&);
  62.       ByteVector(File& F);  // read a ByteVector object from a file
  63.       ~ByteVector(){FreeMemory();}
  64.       void ExtraAlloc(long Quan){Extra=Quan;}
  65.         // each time more memory is needed, this is how much extra is allocated
  66.       Byte huge & operator[](long Index){return Ref(Index);}
  67.         //  To access and modify specific bytes of the vector.
  68.         //  Accessing beyond the current length will increase the vector size.
  69.         //  Completely range protected.
  70.       void operator=(const ByteVector& BV) {Assign(BV);}
  71.       Bool operator==(const ByteVector& S);
  72.       Bool operator!=(const ByteVector& S) { return !(*this==S); }
  73.       // vector concatenation
  74.       ByteVector operator+(const ByteVector& B);
  75.       ByteVector operator+(Byte B);
  76.       friend ByteVector operator+(Byte B, const ByteVector& BV);
  77.       void operator+=(const ByteVector&);
  78.       void operator+=(Byte B) {Ref(Len)=B;}
  79.       operator ConstVoidPointerType(){return P;}
  80.       void CopyTo(void* Dest, long Bytes=MaxSLong); // copy from vector to memory
  81.       void CopyFrom(void* Source, long Bytes); // copy from memory to vector
  82.       //friend void operator=(void* Dest,const ByteVector& BV) {BV.CopyTo(Dest);}
  83.       void WriteTo(File& F);  // write a ByteVector object to file
  84.       long Capacity() {return Alloc;}
  85.       long ReAlloc(long NewCapacity);
  86.       void MinimizeMemory();
  87.         // reduce memory consumption to just what is needed now
  88.       long Size() {return Len;}
  89.       long Index(Byte SearchByte, long StartIndex=0);
  90.         // returns the const NotFound if the Byte is not found in the vector
  91.         // otherwise returns the index
  92.  
  93.       Byte   operator()(long Index); // return an indexed byte.
  94.       ByteVector operator()(long Index, long Length); // return a subvector
  95.       Byte   At(long I);
  96.       ByteVector At(long Index, long Length);
  97.       ByteVector Before(long Index) {return At(0,Index);}
  98.       ByteVector Through(long Index) {return At(0,Index+1);}
  99.       ByteVector From(long Index);
  100.       ByteVector After(long Index);
  101.       void Insert(Byte C,long Index=0);
  102.       void Insert(const ByteVector& BV,long Index=0);
  103.       void Delete(long Index=0,long Length=1);
  104.       void Clear(Byte B=0); // set all elements to B
  105.       long Sum();
  106.       void Empty(){Len=0;}
  107.       void Clip(long NewSize);
  108.       #ifdef MAJORBBS
  109.         void* operator new(size_t size){return malloc(size);}
  110.         void  operator delete(void* p) {free(p);}
  111.       #endif
  112.   };
  113.  
  114. extern Bool BigVectorJump;
  115. /* If true, then vectors in size >64k will always be allocated in chunks of
  116. 64k.  This saves on fragmentation and recopying time. Default is True. */
  117.  
  118. const DefaultVectorExtra=16;
  119.  
  120. /*
  121.  
  122. ByteVector constructors:
  123.  
  124.   I wanted to use a variable argument constructor (see your favorite texts
  125.   on "elipsis", "...", "variable arguments" or "va_arg, va_end and
  126.   va_start") but there were limitations that I felt could lead to very hard
  127.   to find bugs, namely that the applications programmer must first pass a
  128.   value that reveals how many parameters there are.  Being off by one could
  129.   lead to a variety of problems.
  130.  
  131.   There are four ways to construct a ByteVector:
  132.  
  133.     1) ByteVector BV;
  134.  
  135.        This creates a vector that will have a length of 0 although some
  136.        memory will be allocated so that elements may be added later (which
  137.        is the most likely thing to happen).
  138.  
  139.     2) ByteVector BV(1,2,55,8);
  140.  
  141.        This creates a vector of length 4.  You may pass 1 to 9 parameters
  142.        using this type of constructors.  You're limited to 9 because the
  143.        Glock C++ name mangling mixed with MSC 5.1 limits it this way.  An
  144.        update of either of these may solve this problem.
  145.  
  146.     3) static Byte BA[]={1,2,55,8};
  147.        ByteVector BV(BA,4);
  148.  
  149.        This creates a vector of length 4, copying the elements from BA.
  150.        You don't have to copy from an array of bytes, you can use any kind
  151.        of array or even a pointer to anywhere in memory.
  152.  
  153.     4) ByteVector BV2(BV);
  154.  
  155.        Create a ByteVector from another ByteVector.
  156.  
  157. */
  158.  
  159. /*
  160.  
  161.   Note that I use the word "Atomic" in the context that it's used in the
  162.   LISP language, meaning language primitives such as int, long and float.
  163.  
  164.   The classes that are derived from ObjVec using the macros
  165.   "CreateAtomicVectorClass" or "CreateRefVectorClass"are for those types of
  166.   objects that do not need any special class constructors or destructors.
  167.   The former macro passes values through the stack as much as possible.
  168.   The latter passes pointers (as references).  They should both appear to
  169.   work the same way although there may be some differences in time and
  170.   space usage depending on your object size and how you use your vectors.
  171.  
  172.   Again, do not use objects in these vectors that cannot be bit copied,
  173.   such as class objects that contain pointers that require stack
  174.   maintenance.
  175.  
  176. */
  177.  
  178. class ObjVec: private ByteVector
  179.   {
  180.       int  ObjSize;  // size of struct or atomic object:  2 if int, 4 if long, etc.
  181.       int  BlockSize; // see "BlockSize" at bottom of file
  182.       void CtorHelper(int);
  183.     public:
  184.       ObjVec(int ObjectSize);
  185.       ObjVec(int ObjectSize,void*);
  186.       ObjVec(int ObjectSize,void*,void*);
  187.       ObjVec(int ObjectSize,void*,void*,void*);
  188.       ObjVec(int ObjectSize,void* P, long Len);  // copy from some pointer
  189.       ObjVec(const ObjVec&);
  190.  
  191.       void ExtraAlloc(long Quan);
  192.       void* Ref(long Index); // returns pointer to that element
  193.       operator ConstVoidPointerType() const; //{return P;}
  194.       void CopyTo(void* Dest, long Quan=MaxSLong) const; // copy from vector to memory
  195.       void CopyFrom(void* Source, long Quan); // copy to vector from memory
  196.       void WriteTo(File&) const;  // write a ObjVec object to file
  197.       long Capacity() const; // {return (Alloc/ObjSize);}
  198.       long ByteCapacity() const;
  199.       long ReAlloc(long NewCapacity);
  200.       long Size() const; // {return Len/ObjSize);}
  201.       //friend void operator=(void* Dest,const ObjVec& V);
  202.       void operator=(const ObjVec& V);// {Assign(V);}
  203.       //Bool operator==(ObjVec&);
  204.       //Bool operator!=(ObjVec& V);// { return !(*this==V); }
  205.       void operator+=(const ObjVec&);
  206.       ObjVec Concat(const ObjVec&) const;
  207.       ObjVec Concat(void*) const;
  208.       void AppendOneObj(void*);
  209.       ObjVec PrependOneObj(void*) const; // does not modify current obj
  210.       void Insert(const ObjVec& V,long Index=0);
  211.       void Insert(void*,long Index);
  212.       void Delete(long Index=0,long Length=1);
  213.       //void Clear(int X=0); // set all elements to X
  214.       long Sum() const;
  215.       void Empty(); //{Len=0;}
  216.       long Index(void* SearchObj, long StartIndex) const;
  217.       ObjVec At(long,long) const;
  218.       void* At(long) const;
  219.       ObjVec From(long index) const;
  220.       ObjVec After(long index) const;
  221.       void Clip(long NewSize){ByteVector::Clip(NewSize*BlockSize);}
  222.       #ifdef MAJORBBS
  223.         void* operator new(size_t size){return malloc(size);}
  224.         void  operator delete(void* p) {free(p);}
  225.       #endif
  226.   };
  227.  
  228. #define CreateAtomicVectorClass(ClassName,ObjType)                            \
  229. class ClassName:public ObjVec                                                 \
  230.   {                                                                           \
  231.     public:                                                                   \
  232.       ClassName():ObjVec(sizeof(ObjType)){}                                   \
  233.       ClassName(ObjType X):ObjVec(sizeof(ObjType),&X){}                       \
  234.       ClassName(ObjType X1, ObjType X2):ObjVec(sizeof(ObjType),&X1,&X2){}     \
  235.       ClassName(ObjType X1, ObjType X2, ObjType X3)                           \
  236.         :ObjVec(sizeof(ObjType),&X1,&X2,&X3){}                                \
  237.       ClassName(void* P, long Len):ObjVec(sizeof(ObjType),P,Len){}            \
  238.       ClassName(const ClassName& V):ObjVec(V){}                               \
  239.       ClassName(const ObjVec& V):ObjVec(V){}                                  \
  240.       ObjType& Ref(long Index) {return *(ObjType*)ObjVec::Ref(Index);}        \
  241.       ObjType& operator[](long Index){return *(ObjType*)ObjVec::Ref(Index);}  \
  242.       void operator+=(ObjType X){AppendOneObj(&X);}                           \
  243.       void operator+=(ClassName X){ObjVec::operator+=(X);}                    \
  244.       ClassName operator+(const ClassName& V){return ObjVec::Concat(V);}      \
  245.       ClassName operator+(ObjType X){return ObjVec::Concat(&X);}              \
  246.       friend ClassName operator+(ObjType X, const ClassName& V1)              \
  247.         {return V1.PrependOneObj(&X);}                                        \
  248.       long Index(ObjType SearchObj, long StartIndex=0) const                  \
  249.         {return ObjVec::Index(&SearchObj,StartIndex);}                        \
  250.       ObjType operator()(long Index) const                                    \
  251.         {return *(ObjType*)ObjVec::At(Index);}                                \
  252.       ClassName operator()(long Index, long Length) const                     \
  253.         {return ObjVec::At(Index,Length);}                                    \
  254.       ObjType At(long Index){return *(ObjType*)ObjVec::At(Index);}            \
  255.       ClassName At(long Index, long Length)                                   \
  256.         {return ObjVec::At(Index,Length);}                                    \
  257.       ClassName Before(long Index){return ObjVec::At(0,Index);}               \
  258.       ClassName Through(long Index){return ObjVec::At(0,Index+1);}            \
  259.       ClassName From(long Index){return ObjVec::From(Index);}                 \
  260.       ClassName After(long Index){return ObjVec::After(Index);}               \
  261.       void Insert(ObjType C,long Index=0){ObjVec::Insert(&C,Index);}          \
  262.   };
  263.  
  264. #define CreateRefVectorClass(ClassName,ObjType)                               \
  265. class ClassName:public ObjVec                                                 \
  266.   {                                                                           \
  267.     public:                                                                   \
  268.       ClassName():ObjVec(sizeof(ObjType)){}                                   \
  269.       ClassName(ObjType& X):ObjVec(sizeof(ObjType),&X){}                      \
  270.       ClassName(ObjType& X1, ObjType& X2):                                    \
  271.         ObjVec(sizeof(ObjType),&X1,&X2){}                                     \
  272.       ClassName(ObjType& X1, ObjType& X2, ObjType& X3)                        \
  273.         :ObjVec(sizeof(ObjType),&X1,&X2,&X3){}                                \
  274.       ClassName(void* P, long Len):ObjVec(sizeof(ObjType),P,Len){}            \
  275.       ClassName(const ClassName& V):ObjVec(V){}                               \
  276.       ClassName(const ObjVec& V):ObjVec(V){}                                  \
  277.       ObjType& Ref(long Index) {return *(ObjType*)ObjVec::Ref(Index);}        \
  278.       ObjType& operator[](long Index){return Ref(Index);}                     \
  279.       void operator+=(ObjType& X){AppendOneObj(&X);}                          \
  280.       void operator+=(ClassName X){ObjVec::operator+=(X);}                    \
  281.       ClassName operator+(const ClassName& V){return Concat(V);}              \
  282.       ClassName operator+(ObjType& X){return Concat(&X);}                     \
  283.       friend ClassName operator+(ObjType& X, const ClassName& V1)             \
  284.         {return V1.PrependOneObj(&X);}                                        \
  285.       long Index(ObjType& SearchObj, long StartIndex=0)                       \
  286.         {return ObjVec::Index(&SearchObj,StartIndex);}                        \
  287.       ObjType operator()(long Index) {return *(ObjType*)ObjVec::At(Index);}   \
  288.       ClassName operator()(long Index, long Length)                           \
  289.         {return ObjVec::At(Index,Length);}                                    \
  290.       ObjType At(long Index){return *(ObjType*)ObjVec::At(Index);}            \
  291.       ClassName At(long Index, long Length)                                   \
  292.         {return ObjVec::At(Index,Length);}                                    \
  293.       ClassName Before(long Index){return ObjVec::At(0,Index);}               \
  294.       ClassName Through(long Index){return ObjVec::At(0,Index+1);}            \
  295.       ClassName From(long Index){return ObjVec::From(Index);}                 \
  296.       ClassName After(long Index){return ObjVec::After(Index);}               \
  297.       void Insert(ObjType& C,long Index=0){ObjVec::Insert(&C,Index);}         \
  298.   };
  299.  
  300. /*
  301.  
  302. BlockSize
  303.  
  304.   In protected mode (16M uses this) when using large chunks of memory
  305.   (beyond 64K), that represent an array of objects, the objects must occupy
  306.   a space that has a size that is a power of two (1, 2, 4, 8, 16, etc.).
  307.   This is so that a long will not lie on a 64k boundry and assignments will
  308.   be done to it (memory is not contiguous but, rather, in 64k chunks
  309.   managed by a table of contiguous pointers).
  310.  
  311.  
  312. */
  313.  
  314. CreateAtomicVectorClass(IntVector,int);
  315. CreateAtomicVectorClass(LongVector,long);
  316. CreateAtomicVectorClass(CSVector,char*);
  317.  
  318. #endif
  319.  
  320.