"Fossies" - the Fresh Open Source Software Archive

Member "htmlrecode-1.3.1/autoptr" (21 Jul 2009, 5170 Bytes) of package /linux/www/htmlrecode-1.3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #ifndef BqW_autoptr_h
    2 #define BqW_autoptr_h
    3 
    4 /* This is Bisqwit's generic autoptr template file.
    5  * The same file is used in many different projects.
    6  *
    7  * This class, autoptr, implements a reference-counting
    8  * pointer object.
    9  *
   10  * Usage example:
   11  *   #include <iostream>
   12  *   #include "autoptr"
   13  *   
   14  *   class thing: public ptrable
   15  *   {
   16  *   public:
   17  *       thing() { std::cout << "thing sprouts\n"; }
   18  *       ~thing() { std::cout << "thing dies\n"; }
   19  *   };
   20  *
   21  *   int main()
   22  *   {
   23  *      autoptr<thing> p = new thing;
   24  *      autoptr<thing> k = p;
   25  *   }
   26  * 
   27  *   "thing" is automatically destroyed when
   28  *   all autopointers referring to it have died.
   29  *
   30  *   Virtual and non-virtual classes are supported.
   31  *
   32  * autoptr.hh version 1.3.11
   33  *
   34  * The difference to boost::shared_ptr<> is that
   35  * my autoptr does not keep two pointers around.
   36  * Instead, it requires the pointed object to be
   37  * derived from "ptrable" so that it contains the
   38  * reference count in it.
   39  */
   40 
   41 /* Basic autopointer type. Can only point to ptrable-derived classes. */
   42 template <typename T>
   43 class autoptr
   44 {
   45     inline void Forget() { if(p) { p->_ptr_lost_you(); if(p->_ptr_is_dead()) delete p; } }
   46     inline void Have(T *const a) const { if(a) a->_ptr_got_you(); }
   47     inline void Set(T *const a) { Have(a); Forget(); p = a; }
   48     inline void Birth() { Have(p); }
   49     T *p;
   50 public:
   51     autoptr() : p(0) { }
   52     autoptr(T *const a) : p(a) { Birth(); }
   53     autoptr(const autoptr &a) : p(&*a) { Birth(); }
   54     
   55     // To enable boolean tests with this class: if(tmp) {...}
   56     inline operator bool() const { return p; }
   57     inline bool operator! () const { return !p; }
   58     
   59     // Act like if you were a pointer (for comparisons etc)
   60     inline operator T* () const { return p; }
   61     inline bool operator< (const autoptr &a) const { return p < a.p; }
   62     
   63     // Dereferencing
   64     inline T &operator* () const { return *p; }
   65     inline T *operator-> () const { return p; }
   66     
   67     // Assigning
   68     autoptr &operator= (T *const a) { Set(a); return *this; }
   69     autoptr &operator= (const autoptr &a) { Set(&*a); return *this; }
   70     void reset(T *const a) { Set(a); }
   71     void reset(const autoptr &a) { Set(&*a); }
   72     
   73     // Other
   74     bool isShared() const { return p->get_autoptr_refnum() > 1; }
   75     
   76     ~autoptr() { Forget(); }
   77 private:
   78     // This conversion shouldn't be available
   79     //operator T*& ();
   80 };
   81 
   82 /* A pointer type where pointer comparison does actually a value
   83  * comparison. Useful if you want to use pointers in a sorted container.
   84  */
   85 template <typename T>
   86 class autoeqptr : public autoptr<T>
   87 {
   88 public:
   89     autoeqptr() { }
   90     autoeqptr(T *const a) : autoptr<T> (a) { }
   91     
   92     template<typename K> inline bool operator== (K s) const { return **this == *s; }
   93     template<typename K> inline bool operator< (K s) const { return **this < *s; }
   94     // enable these too if you see them necessary
   95   /*
   96     template<typename K> inline bool operator!= (K s) const { return **this != *s; }
   97     template<typename K> inline bool operator> (K s) const { return **this > *s; }
   98     template<typename K> inline bool operator<= (K s) const { return **this <= *s; }
   99     template<typename K> inline bool operator=> (K s) const { return **this => *s; }
  100   */
  101 };
  102 
  103 // autoptr must only use ptrable classes.
  104 class ptrable
  105 {
  106     mutable unsigned long _ptr_ref_num;
  107 private:
  108     template<typename> friend class autoptr;
  109 
  110     inline void _ptr_got_you() const
  111     {
  112      /* This ifdef is not really required, but it avoids
  113       * a nasty warning when the compiler does not support
  114       * that #pragma directive.
  115       */
  116      #ifdef __OPENMP
  117       #pragma omp atomic
  118      #endif
  119         ++_ptr_ref_num;
  120     }
  121     inline void _ptr_lost_you() const
  122     {
  123      #ifdef __OPENMP
  124       #pragma omp atomic
  125      #endif
  126         --_ptr_ref_num;
  127     }
  128     /* ptr_lost_you may not do "delete this", because the destructor is not
  129      * virtual. Deletion must be done by the caller (autoptr::Forget()), who
  130      * knows what this class actually is and how to delete it.
  131      */
  132     inline bool _ptr_is_dead() const { return !_ptr_ref_num; }
  133 public:
  134     /* Birth with refnum 0, not 1.
  135      * Refnum tells how many autoptr's are referring to this.
  136      */
  137     ptrable() : _ptr_ref_num(0) { }
  138     
  139     /* Copied element has no referrals, for the same reason. */
  140     ptrable(const ptrable &) : _ptr_ref_num(0) { }
  141     
  142     /* */
  143     ptrable& operator=(const ptrable& ) { /* No changes to referrals */ return *this; }
  144     
  145     /* ptrable does not need to contain a virtual destructor,
  146      * because even though classes may be derived from ptrable,
  147      * plain pointers to ptrable are never expected to be formed.
  148      */
  149     
  150     /* Debugging purposes */
  151     inline unsigned long get_autoptr_refnum() const { return _ptr_ref_num; }
  152 };
  153 
  154 template<typename T>
  155 class ptrable_autoptr: public autoptr<T>, public ptrable
  156 {
  157 public:
  158     ptrable_autoptr() : autoptr<T>(), ptrable() { }
  159     ptrable_autoptr(T *const a) : autoptr<T>(a), ptrable() { }
  160     ptrable_autoptr(const ptrable_autoptr &a) : autoptr<T>(a), ptrable(a) { }
  161 
  162     inline operator T* () const { return autoptr<T>::operator T* (); }
  163 };
  164 
  165 #endif