mixpp: shared_ptr.h Source File

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 "bdmerror.h"
00021
00022 namespace bdm {
00023
00033 template <typename T>
00034 class shared_ptr {
00035     template<class U> friend class shared_ptr;
00036
00037 private:
00038     T *payload;
00039     unsigned *refCnt;
00040
00041 public:
00047     shared_ptr() :
00048         payload ( 0 ),
00049         refCnt ( 0 ) {
00050     }
00051
00058     shared_ptr ( T *p ) :
00059         payload ( p ),
00060         refCnt ( p ? new unsigned ( 1 ) : 0 ) {
00061     }
00062
00069     shared_ptr ( const shared_ptr<T> &other ) :
00070         payload ( other.payload ),
00071         refCnt ( other.refCnt ) {
00072         add_ref();
00073     }
00074
00084     template<typename U>
00085     shared_ptr ( const shared_ptr<U> &other ) :
00086         payload ( other.payload ),
00087         refCnt ( other.refCnt ) {
00088         add_ref();
00089     }
00090
00094     ~shared_ptr() {
00095         del_ref();
00096     }
00097
00101     shared_ptr<T> &operator= ( const shared_ptr<T> &other ) {
00102         other.add_ref();
00103         del_ref();
00104
00105         payload = other.payload;
00106         refCnt = other.refCnt;
00107
00108         return *this;
00109     }
00110
00115     T *get() {
00116         return payload;
00117     }
00118
00124     T *operator->() {
00125         bdm_assert_debug ( payload, "dereferencing NULL shared pointer" );
00126         return payload;
00127     }
00128
00132     T &operator*() {
00133         bdm_assert_debug ( payload, "dereferencing NULL shared pointer" );
00134         return *payload;
00135     }
00136
00141     const T* get() const {
00142         return payload;
00143     }
00144
00148     const T *operator->() const {
00149         bdm_assert_debug ( payload, "dereferencing NULL shared pointer" );
00150         return payload;
00151     }
00152
00156     const T &operator*() const {
00157         bdm_assert_debug ( payload, "dereferencing NULL shared pointer" );
00158         return *payload;
00159     }
00160
00162     bool unique() const {
00163         return refCnt && ( *refCnt == 1 );
00164     }
00165
00171     long use_count() const {
00172         return refCnt ? *refCnt : 0;
00173     }
00174
00180     operator bool() const {
00181         return !!payload;
00182     }
00183
00190     template<typename U>
00191     operator shared_ptr<const U>() const {
00192         shared_ptr<const U> cptr;
00193         cptr.refCnt = refCnt;
00194         cptr.payload = payload;
00195         add_ref();
00196         return cptr;
00197     }
00198
00202     void swap ( shared_ptr &other ) {
00203         std::swap ( payload, other.payload );
00204         std::swap ( refCnt, other.refCnt );
00205     }
00206
00207 private:
00208     void add_ref() const {
00209         if ( refCnt ) {
00210             if ( *refCnt == UINT_MAX ) {
00211                 throw std::overflow_error (
00212                     std::string ( "Shared pointer has too many references." ) );
00213             }
00214
00215             ++*refCnt;
00216         }
00217     }
00218
00219     void del_ref() {
00220         if ( refCnt ) {
00221             if ( ! ( --*refCnt ) ) {
00222                 delete payload;
00223                 delete refCnt;
00224             }
00225         }
00226     }
00227 };
00228
00230 template<typename T, typename U>
00231 bool operator== ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
00232     return a.get() == b.get();
00233 }
00234
00236 template<typename T, typename U>
00237 bool operator!= ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
00238     return a.get() != b.get();
00239 }
00240
00242 template<typename T, typename U>
00243 bool operator< ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
00244     return a.get() < b.get();
00245 }
00246
00254 template <typename T>
00255 class object_ptr : public shared_ptr<T> {
00256 public:
00262     object_ptr() : shared_ptr<T> ( new T() ) { }
00263
00269     object_ptr ( const shared_ptr<T> &b ) : shared_ptr<T> ( b ) {
00270         bdm_assert_debug ( this->get(), "object_ptr cannot be empty" );
00271     }
00272
00277     object_ptr ( T *p ) : shared_ptr<T> ( p ) {
00278         bdm_assert_debug ( p, "object_ptr cannot be empty" );
00279     }
00280
00284     object_ptr<T> &operator= ( const object_ptr<T> &other ) {
00285         shared_ptr<T>::operator= ( other );
00286         return *this;
00287     }
00288 };
00289
00290 #define SHAREDPTR(class_name) typedef bdm::object_ptr< class_name > class_name##_ptr
00291 
00292 #define SHAREDPTR2(template_class_name, template_parameter_name) typedef bdm::object_ptr< template_class_name < template_parameter_name > > template_class_name##_##template_parameter_name##_ptr
00293 
00294 }
00295
00296 #endif

Generated on 2 Dec 2013 for mixpp by  doxygen 1.4.7