- Main Page
- Related Pages
- Classes
- Files

- File List
- File Members

# shared_ptr.h

Go to the documentation of this file.

    00001
    00013 #ifndef shared_ptr_h
    00014 #define shared_ptr_h
    00015
    00016 #include <limits.h>
    00017 #include <algorithm>
    00018 #include <stdexcept>
    00019 #include <string>
    00020 #include "itpp_ext.h"
    00021
    00022 namespace bdm {
    00023
    00025 // The standard template would naturally be preferable, _if_ it was
    00026 // included in the standard libraries of all supported compilers - but
    00027 // that's exactly what remains to be seen...
    00028 template <typename T>
    00029 class shared_ptr {
    00030     template<class U> friend class shared_ptr;
    00031
    00032 private:
    00033     T *payload;
    00034     unsigned *refCnt;
    00035
    00036 public:
    00038     shared_ptr():
    00039         payload(0),
    00040         refCnt(0)
    00041     {
    00042     }
    00043
    00047     shared_ptr(T *p):
    00048         payload(p),
    00049         refCnt(p ? new unsigned(1) : 0)
    00050     {
    00051     }
    00052
    00055     shared_ptr(const shared_ptr<T> &other):
    00056         payload(other.payload),
    00057         refCnt(other.refCnt)
    00058     {
    00059         add_ref();
    00060     }
    00061
    00064     template<typename U>
    00065     shared_ptr(const shared_ptr<U> &other):
    00066         payload(other.payload),
    00067         refCnt(other.refCnt)
    00068     {
    00069         add_ref();
    00070     }
    00071
    00072     ~shared_ptr()
    00073     {
    00074         del_ref();
    00075     }
    00076
    00077     shared_ptr &operator=(const shared_ptr &other)
    00078     {
    00079         other.add_ref();
    00080         del_ref();
    00081
    00082         payload = other.payload;
    00083         refCnt = other.refCnt;
    00084
    00085         return *this;
    00086     }
    00087
    00090     T *get() { return payload; }
    00091
    00095     T *operator->()
    00096     {
    00097         it_assert_debug(payload, "dereferencing NULL");
    00098         return payload;
    00099     }
    00100
    00104     T &operator*()
    00105     {
    00106         it_assert_debug(payload, "dereferencing NULL");
    00107         return *payload;
    00108     }
    00109
    00112     const T* get() const { return payload; }
    00113
    00117     const T *operator->() const
    00118     {
    00119         it_assert_debug(payload, "dereferencing NULL");
    00120         return payload;
    00121     }
    00122
    00126     const T &operator*() const
    00127     {
    00128         it_assert_debug(payload, "dereferencing NULL");
    00129         return *payload;
    00130     }
    00131
    00132     bool unique() const
    00133     {
    00134         return refCnt && (*refCnt == 1);
    00135     }
    00136
    00137     long use_count() const
    00138     {
    00139         return refCnt ? *refCnt : 0;
    00140     }
    00141
    00142     operator bool() const
    00143     {
    00144       return payload;
    00145     }
    00146
    00147     void swap(shared_ptr &other)
    00148     {
    00149         std::swap(payload, other.payload);
    00150         std::swap(refCnt, other.refCnt);
    00151     }
    00152
    00153 private:
    00154     void add_ref() const
    00155     {
    00156         if (refCnt) {
    00157             if (*refCnt == UINT_MAX) {
    00158                 throw std::overflow_error(
    00159                     std::string("Shared pointer has too many references."));
    00160             }
    00161
    00162             ++*refCnt;
    00163         }
    00164     }
    00165
    00166     void del_ref()
    00167     {
    00168         if (refCnt) {
    00169             if (!(--*refCnt)) {
    00170                 delete payload;
    00171                 delete refCnt;
    00172             }
    00173         }
    00174     }
    00175 };
    00176
    00177 template<typename T, typename U>
    00178 bool operator==(shared_ptr<T> const &a, shared_ptr<U> const &b)
    00179 {
    00180     return a.get() == b.get();
    00181 }
    00182
    00183 template<typename T, typename U>
    00184 bool operator!=(shared_ptr<T> const &a, shared_ptr<U> const &b)
    00185 {
    00186     return a.get() != b.get();
    00187 }
    00188
    00189 template<typename T, typename U>
    00190 bool operator<(shared_ptr<T> const &a, shared_ptr<U> const &b)
    00191 {
    00192     return a.get() < b.get();
    00193 }
    00194
    00195 }
    00196
    00197 #endif