home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / CLASSINC.PAK / POINTER.H < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  6.2 KB  |  211 lines

  1. //----------------------------------------------------------------------------
  2. // Borland Class Library
  3. // Copyright (c) 1992, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   5.10  $
  6. //
  7. // Various types of smart pointer templatized classes
  8. //----------------------------------------------------------------------------
  9. #if !defined(CLASSLIB_POINTER_H)
  10. #define CLASSLIB_POINTER_H
  11.  
  12. #if !defined(CLASSLIB_DEFS_H)
  13. # include <classlib/defs.h>
  14. #endif
  15. #include <new.h>  // for size_t
  16.  
  17. #if defined(BI_NAMESPACE)
  18. namespace ClassLib {
  19. #endif
  20.  
  21. //
  22. // A pair of smart pointer template classes. Provides basic conversion
  23. // operator to T*, as well as dereferencing (*), and 0-checking (!).
  24. // These classes assume that they alone are responsible for deleting the
  25. // object or array unless Relinquish() is called.
  26. //
  27.  
  28. //
  29. // class TPointerBase
  30. // ~~~~~ ~~~~~~~~~~~~
  31. template<class T> class TPointerBase {
  32.   public:
  33.     T&   operator  *() {return *P;}
  34.          operator T*() {return P;}
  35.     int  operator  !() const {return P==0;}
  36.     T*   Relinquish() {T* p = P; P = 0; return p;}
  37.  
  38.   protected:
  39.     TPointerBase(T* pointer) : P(pointer) {}
  40.     TPointerBase() : P(0) {}
  41.  
  42.     T* P;
  43.  
  44.   private:
  45.     void* operator new(size_t) {return 0;}  // prohibit use of new
  46.     void operator delete(void* p) {((TPointerBase<T>*)p)->P=0;}
  47. };
  48.  
  49. //
  50. // class TPointer
  51. // ~~~~~ ~~~~~~~~
  52. // Pointer to a single object. Provides member access operator ->
  53. //
  54. template<class T> class TPointer : public TPointerBase<T> {
  55.   public:
  56.     TPointer() : TPointerBase<T>() {}
  57.     TPointer(T* pointer) : TPointerBase<T>(pointer) {}
  58.    ~TPointer() {delete P;}
  59.     TPointer<T>& operator =(T* src) {delete P; P = src; return *this;}
  60.     T* operator->() {return P;}  // Could throw exception if P==0
  61. };
  62.  
  63. //
  64. // class TAPointer
  65. // ~~~~~ ~~~~~~~~~
  66. // Pointer to an array of type T. Provides an array subscript operator and uses
  67. // array delete[]
  68. //
  69. template<class T> class TAPointer : public TPointerBase<T> {
  70.   public:
  71.     TAPointer() : TPointerBase<T>() {}
  72.     TAPointer(T array[]) : TPointerBase<T>(array) {}
  73.    ~TAPointer() {delete[] P;}
  74.     TAPointer<T>& operator =(T src[]) {delete[] P; P = src; return *this;}
  75.     T& operator[](int i) {return P[i];}  // Could throw exception if P==0
  76. };
  77.  
  78. //----------------------------------------------------------------------------
  79.  
  80. //
  81. // Envelope-letter type of smart pointers. In this implementation the envelope
  82. // acts as a smart pointer to a reference-counted internal letter. This allows
  83. // a lot of flexibility & safety in working with a single object (associated
  84. // with the letter) being assigned to numerous envelopes in many scopes. An 'A'
  85. // version is provided for use with arrays.
  86. //
  87. // Use like:
  88. //   TEnvelope<T> e1 = new T(x,y,x);   // e1 now owns a T in a letter
  89. //   e1->Func();                       // invokes Func() on the new T
  90. //   Func(*e1);                        // passing a T& or a T this way
  91. //   TEnvelope<T> e2 = e1;             // e2 safely shares the letter with e1
  92. //
  93. //   TAEnvelope<T> e1 = new T[99];     // e1 now owns T[] in a letter
  94. //   e1[i].Func();                     // invokes Func() on a T element
  95. //   Func(e1[i]);                      // passing a T& or a T this way
  96. //   TAEnvelope<T> e2 = e1;            // e2 safely shares the letter with e1
  97. //
  98.  
  99. //
  100. // class TEnvelope
  101. // ~~~~~ ~~~~~~~~~
  102. template<class T> class TEnvelope {
  103.   public:
  104.     TEnvelope(T* object) : Letter(new TLetter(object)) {}
  105.     TEnvelope(const TEnvelope& src) : Letter(src.Letter) {Letter->AddRef();}
  106.    ~TEnvelope() {Letter->Release();}
  107.  
  108.     TEnvelope& operator =(const TEnvelope& src);
  109.     TEnvelope& operator =(T* object);
  110.  
  111.     T* operator->() { return Letter->Object; }
  112.     T& operator *() { return *Letter->Object; }
  113.  
  114.   private:
  115.     struct TLetter {
  116.       TLetter(T* object) : Object(object), RefCount(1) {}
  117.      ~TLetter() { delete Object; }
  118.  
  119.       void AddRef() { RefCount++; }
  120.       void Release() { if (--RefCount == 0) delete this; }
  121.  
  122.       T*  Object;
  123.       int RefCount;
  124.     };
  125.     TLetter* Letter;
  126. };
  127.  
  128. template<class T>
  129. TEnvelope<T>& TEnvelope<T>::operator =(const TEnvelope<T>& src)
  130. {
  131.   Letter->Release();
  132.   Letter = src.Letter;
  133.   Letter->AddRef();
  134.   return *this;
  135. }
  136.  
  137. template<class T>
  138. TEnvelope<T>& TEnvelope<T>::operator =(T* object)
  139. {
  140.   Letter->Release();
  141.   Letter = new TLetter(object);  // Assumes non-null! Use with new
  142.   return *this;
  143. }
  144.  
  145. //
  146. // class TAEnvelope
  147. // ~~~~~ ~~~~~~~~~~
  148. template<class T> class TAEnvelope {
  149.   public:
  150.     TAEnvelope(T array[]) : Letter(new TLetter(array)) {}
  151.     TAEnvelope(const TAEnvelope& src) : Letter(src.Letter) {Letter->AddRef();}
  152.    ~TAEnvelope() { Letter->Release(); }
  153.  
  154.     TAEnvelope& operator =(const TAEnvelope& src);
  155.     TAEnvelope& operator =(T array[]);
  156.  
  157.     T& operator[](int i) { return Letter->Array[i]; }
  158.     T* operator *() { return Letter->Array; }
  159.  
  160.   private:
  161.     struct TLetter {
  162.       TLetter(T array[]) : Array(array), RefCount(1) {}
  163.      ~TLetter() { delete[] Array; }
  164.  
  165.       void AddRef() { RefCount++; }
  166.       void Release() { if (--RefCount == 0) delete this; }
  167.  
  168.       T*  Array;
  169.       int RefCount;
  170.     };
  171.     TLetter* Letter;
  172. };
  173.  
  174. template<class T>
  175. TAEnvelope<T>& TAEnvelope<T>::operator =(const TAEnvelope<T>& src)
  176. {
  177.   Letter->Release();
  178.   Letter = src.Letter;
  179.   Letter->AddRef();
  180.   return *this;
  181. }
  182.  
  183. template<class T>
  184. TAEnvelope<T>& TAEnvelope<T>::operator =(T array[])
  185. {
  186.   Letter->Release();
  187.   Letter = new TLetter(array);  // Assumes non-null! Use with new
  188.   return *this;
  189. }
  190.  
  191. //----------------------------------------------------------------------------
  192.  
  193. //
  194. // Obsolete, should use TAPointer<_TCHAR> for _TCHAR[]'s
  195. //
  196. class TPointer<_TCHAR> : public TPointerBase<_TCHAR> {
  197.   public:
  198.     TPointer() : TPointerBase<_TCHAR>() {}
  199.     TPointer(_TCHAR pointer[]) : TPointerBase<_TCHAR>(pointer) {}
  200.    ~TPointer() {delete[] P;}
  201.     _TCHAR* operator =(_TCHAR src[]) {delete[] P; return P = src;}
  202.     _TCHAR* operator =(const TPointer<_TCHAR>& src) {delete[] P; return P = src.P;}
  203.     _TCHAR& operator[](int i) {return P[i];}
  204. };
  205.  
  206. #if defined(BI_NAMESPACE)
  207. }   // namespace ClassLib
  208. #endif
  209.  
  210. #endif  // CLASSLIB_POINTER_H
  211.