halapi hierarchichalalignmentformatapi

- Main Page
- Namespaces
- Classes
- Files

- File List

inc/counted_ptr.h

    00001 /*
    00002  * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
    00003  *
    00004  * Released under the MIT license, see LICENSE.txt
    00005  */
    00006
    00007
    00018 /*
    00019  * counted_ptr - simple reference counted pointer.
    00020  *
    00021  * The is a non-intrusive implementation that allocates an additional
    00022  * int and pointer for every counted object.
    00023  */
    00024
    00025 #ifndef COUNTED_PTR_H
    00026 #define COUNTED_PTR_H
    00027
    00028 /* For ANSI-challenged compilers, you may want to #define
    00029  * NO_MEMBER_TEMPLATES or explicit */
    00030
    00031 namespace hal {
    00032
    00033 template <typename T>
    00034 struct counted_ptr_remove_const
    00035 {
    00036     typedef T type;
    00037 };
    00038 template <typename T>
    00039 struct counted_ptr_remove_const<const T>
    00040 {
    00041     typedef T type;
    00042 };
    00043
    00044 template<typename X>
    00045 struct ptr_counter {
    00046    ptr_counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
    00047    X*          ptr;
    00048    unsigned    count;
    00049 };
    00050
    00051 template<typename X>
    00052 struct ptr_counter<const X> {
    00053    ptr_counter(const X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
    00054    const X*          ptr;
    00055    unsigned    count;
    00056
    00057    ptr_counter& operator=(const ptr_counter<typename counted_ptr_remove_const<X>::type>& other) {
    00058      ptr = other.ptr;
    00059      count = other.count;
    00060    }
    00061 };
    00062 template <class X> class counted_ptr
    00063 {
    00064 public:
    00065    friend class counted_ptr<const X>;
    00066    typedef X element_type;
    00067    typedef ptr_counter<X> counter;
    00068
    00069     explicit counted_ptr(X* p = 0) // allocate a new counter
    00070       : itsCounter(0) {if (p) itsCounter = new counter(p);}
    00071     ~counted_ptr()
    00072         {release();}
    00073     counted_ptr(const counted_ptr& r) throw()
    00074         {acquire(r.itsCounter);}
    00075     counted_ptr& operator=(const counted_ptr& r)
    00076     {
    00077         if (this != &r) {
    00078             release();
    00079             acquire(r.itsCounter);
    00080         }
    00081         return *this;
    00082     }
    00083
    00084
    00085
    00086     /*
    00087 #ifndef NO_MEMBER_TEMPLATES
    00088     template <class Y> friend class counted_ptr<Y>;
    00089     template <class Y> counted_ptr(const counted_ptr<Y>& r) throw()
    00090         {acquire(r.itsCounter);}
    00091     template <class Y> counted_ptr& operator=(const counted_ptr<Y>& r)
    00092     {
    00093         if (this != &r) {
    00094             release();
    00095             acquire(r.itsCounter);
    00096         }
    00097         return *this;
    00098     }
    00099 #endif // NO_MEMBER_TEMPLATES
    00100     */
    00101
    00102     X& operator*()  const throw()   {return *itsCounter->ptr;}
    00103     X* operator->() const throw()   {return itsCounter->ptr;}
    00104     X* get()        const throw()   {return itsCounter ? itsCounter->ptr : 0;}
    00105     bool unique()   const throw()
    00106         {return (itsCounter ? itsCounter->count == 1 : true);}
    00107
    00108 private:
    00109
    00110    counter* itsCounter;
    00111
    00112     void acquire(counter* c) throw()
    00113     { // increment the count
    00114         itsCounter = c;
    00115         if (c) ++c->count;
    00116     }
    00117
    00118     void release()
    00119     { // decrement the count, delete if it is 0
    00120         if (itsCounter) {
    00121             if (--itsCounter->count == 0) {
    00122                 delete itsCounter->ptr;
    00123                 delete itsCounter;
    00124             }
    00125             itsCounter = 0;
    00126         }
    00127     }
    00128 };
    00129
    00130
    00131 template <class X> class counted_ptr<const X>
    00132 {
    00133 public:
    00134     typedef const X element_type;
    00135    typedef ptr_counter<const X> counter;
    00136
    00137     explicit counted_ptr(const X* p = 0) // allocate a new counter
    00138         : itsCounter(0) {if (p) itsCounter = new counter(p);}
    00139    ~counted_ptr()
    00140         {release();}
    00141     counted_ptr(const counted_ptr& r) throw()
    00142         {acquire(r.itsCounter);}
    00143     counted_ptr& operator=(const counted_ptr& r)
    00144     {
    00145         if (this != &r) {
    00146             release();
    00147             acquire(r.itsCounter);
    00148         }
    00149         return *this;
    00150     }
    00151
    00152    counted_ptr(const counted_ptr<typename counted_ptr_remove_const<X>::type>& r) throw()
    00153       {acquire(r.itsCounter);}
    00154    counted_ptr& operator=(const counted_ptr<typename counted_ptr_remove_const<X>::type>& r)
    00155    {
    00156      if (this != &r) {
    00157        release();
    00158        acquire(r.itsCounter);
    00159      }
    00160      return *this;
    00161    }
    00162 /*
    00163 #ifndef NO_MEMBER_TEMPLATES
    00164     template <class Y> friend class counted_ptr<Y>;
    00165     template <class Y> counted_ptr(const counted_ptr<Y>& r) throw()
    00166         {acquire(r.itsCounter);}
    00167     template <class Y> counted_ptr& operator=(const counted_ptr<Y>& r)
    00168     {
    00169         if (this != &r) {
    00170             release();
    00171             acquire(r.itsCounter);
    00172         }
    00173         return *this;
    00174     }
    00175 #endif // NO_MEMBER_TEMPLATES
    00176 */
    00177     const X& operator*()  const throw()   {return *itsCounter->ptr;}
    00178     const X* operator->() const throw()   {return itsCounter->ptr;}
    00179     const X* get()        const throw()   {return itsCounter ? itsCounter->ptr : 0;}
    00180     bool unique()   const throw()
    00181         {return (itsCounter ? itsCounter->count == 1 : true);}
    00182
    00183 private:
    00184
    00185    counter* itsCounter;
    00186
    00187     void acquire(counter* c) throw()
    00188     { // increment the count
    00189         itsCounter = c;
    00190         if (c) ++c->count;
    00191     }
    00192
    00193     void acquire(ptr_counter<typename counted_ptr_remove_const<X>::type>* c) throw()
    00194     { // increment the count
    00195       itsCounter = (ptr_counter<const X>*)c;
    00196         if (c) ++c->count;
    00197     }
    00198
    00199     void release()
    00200     { // decrement the count, delete if it is 0
    00201         if (itsCounter) {
    00202             if (--itsCounter->count == 0) {
    00203                 delete itsCounter->ptr;
    00204                 delete itsCounter;
    00205             }
    00206             itsCounter = 0;
    00207         }
    00208     }
    00209 };
    00210 }
    00211 #endif // COUNTED_PTR_H

All Classes Namespaces Functions