home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / code / bcpp / file19 / vector.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  5.0 KB  |  199 lines

  1. /////////////////////////////////////////////////////////////
  2. // vector.h: Fixed-length shared vector template.
  3. // Copyright(c) 1993 Azarona Software. All rights reserved.
  4. /////////////////////////////////////////////////////////////
  5. #ifndef H_VECTOR
  6. #define H_VECTOR
  7. #include "range.h"
  8. #include "vecptr.h"
  9.  
  10. #define INLINE
  11.  
  12. enum SliceType { SHARED, COPIED };
  13.  
  14. // Vector representation class. Private to the vector class.
  15.  
  16. template<class TYPE> class Vector; // Forward template declaration
  17.  
  18. template<class TYPE>
  19. class VecRep {
  20. // WARNING: VecRep objects are meant to be allocated only 
  21. // dynamically. The only exception is null_rep, which is
  22. // a special null version of a VecRep object. Only one
  23. // of these should be created.
  24. #ifdef NO_BORLAND_BUG
  25. private:
  26.   friend class Vector<TYPE>;
  27. #else
  28. public:
  29. #endif
  30.   unsigned alloclen;
  31.   unsigned refcnt;
  32.   TYPE data[1];
  33.   VecRep(unsigned d);
  34.   void *operator new(size_t n, unsigned d);
  35.   void operator delete(void *p);
  36. public: // So we can set up null_rep
  37.   static VecRep<TYPE> null_rep;
  38.   VecRep();
  39.   ~VecRep();
  40. };
  41.  
  42. // You need to call this for each type of vector, to 
  43. // set up the special null VecRep object. Do it only
  44. // once though.
  45.  
  46. #define INITNULLVEC(TYPE) VecRep<TYPE> VecRep<TYPE>::null_rep;
  47.  
  48.  
  49. // The vector class
  50.  
  51. template<class TYPE> class Matrix; // Forward template declaration
  52.  
  53. template<class TYPE>
  54. class Vector {
  55. protected:
  56.   friend class Matrix<TYPE>;
  57.   VecRep<TYPE> *rep; // Pointer to shared vector data
  58.   TYPE *start;       // Pointer to logical start of data
  59.   unsigned len;      // Number of logical elements
  60.   unsigned stride;   // Stride (offset to next logical element)
  61.   int Alloc(unsigned n);
  62.   void Bind(const Vector<TYPE> &v);
  63.   void Unbind();
  64.   void NewBinding(const Vector<TYPE> &v);
  65. public:
  66.   Vector(unsigned n = 0, const TYPE *s = 0);
  67.   Vector(const Vector<TYPE> &v);
  68.   Vector(const Vector<TYPE> &v, SliceType styp,
  69.          unsigned n=0, unsigned str=1, unsigned ofs=0);
  70.   ~Vector();
  71. #ifndef NO_RANGE_CHECK
  72.   unsigned CheckIndx(unsigned i) const;
  73. #endif
  74.   // We'll provide both forms of subscripting
  75.   TYPE &operator[](unsigned i);
  76.   const TYPE &operator[](unsigned i) const;
  77.   void CopyN(const TYPE *src, unsigned n);
  78.   void Copy(const Vector<TYPE> &v);
  79.   void Share(const Vector<TYPE> &v);
  80.   void SetElements(const TYPE &x);
  81.   Vector<TYPE> &operator=(const Vector<TYPE> &v);
  82.   Vector<TYPE> &operator=(const TYPE &x);
  83.   int IsNull() const;
  84.   int IsUnique() const;
  85.   Vector<TYPE> Clone() const;
  86.   int EnsureUnique();
  87.   unsigned Length() const;
  88.   unsigned Stride() const;
  89.   // Low-level hooks
  90.   VecPtr<TYPE> PtrToAll();
  91.   VecPtr<const TYPE> PtrToAll() const;
  92. };
  93.  
  94. template<class TYPE>
  95. INLINE VecRep<TYPE>::VecRep()
  96. // Constructor to form a null VecRep object.
  97. // This object should only be allocated statically.
  98. // NOTE: TYPE's default constructor called implicitly.
  99. {
  100.   alloclen = 1;
  101.   refcnt = 1;
  102. }
  103.  
  104. template<class TYPE>
  105. INLINE Vector<TYPE>::~Vector()
  106. // Destructor unbinds this vector from the data
  107. // it was sharing.
  108.   Unbind(); 
  109. }
  110.  
  111.  
  112. template<class TYPE>
  113. INLINE TYPE &Vector<TYPE>::operator[](unsigned i) 
  114. // For non-const vectors.
  115.   return start[CHECK(i)*stride]; 
  116. }
  117.  
  118.  
  119. template<class TYPE>
  120. INLINE const TYPE &Vector<TYPE>::operator[](unsigned i) const 
  121. // For const vectors.
  122.   return start[CHECK(i)*stride]; 
  123. }
  124.  
  125. template<class TYPE>
  126. INLINE Vector<TYPE> &Vector<TYPE>::operator=(const Vector<TYPE> &v)
  127. // Share semantics used for assignment.
  128.   if (this != &v) Share(v); // Note trap for assignment to self
  129.   return *this; 
  130. }
  131.  
  132. template<class TYPE>
  133. INLINE Vector<TYPE> &Vector<TYPE>::operator=(const TYPE &x)
  134. // Sets each element of the vector to the value x.
  135. {
  136.   SetElements(x);
  137.   return *this;
  138. }
  139.  
  140. template<class TYPE>
  141. INLINE int Vector<TYPE>::IsNull() const
  142. // Returns true if the vector references null_rep.
  143. {
  144.   return rep == &VecRep<TYPE>::null_rep;
  145. }
  146.  
  147. template<class TYPE>
  148. INLINE int Vector<TYPE>::IsUnique() const
  149. // Returns true if vector has only reference to shared data,
  150. // or the shared data is null_rep.
  151. {
  152.   return rep->refcnt == 1 || IsNull();
  153. }
  154.  
  155.  
  156. template<class TYPE>
  157. INLINE unsigned Vector<TYPE>::Length() const
  158. // Return the logical number of elements of the vector.
  159.   return len; 
  160. }
  161.  
  162. template<class TYPE>
  163. INLINE unsigned Vector<TYPE>::Stride() const 
  164. // Return the vector's stride (ie. offset between
  165. // each logical element.)
  166. {
  167.   return stride; 
  168. }
  169.  
  170. template<class TYPE>
  171. INLINE VecPtr<TYPE> Vector<TYPE>::PtrToAll()
  172. // Returns a vector pointer to the beginning of
  173. // this vector's elements.
  174.   return VecPtr<TYPE>(start, stride); 
  175. }
  176.  
  177. template<class TYPE>
  178. INLINE VecPtr<const TYPE> Vector<TYPE>::PtrToAll() const
  179. // Returns a vector pointer to the beginning of
  180. // this vector's elements.
  181.   return VecPtr<const TYPE>(start, stride); 
  182. }
  183.  
  184. #undef INLINE
  185.  
  186. // Whether or not we should include the non-line methods for
  187. // our class templates here is implementation dependent.
  188.  
  189. #include "vector.mth"
  190.  
  191. #endif
  192.