- 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 "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                 if ( !payload) {abort();};// "dereferencing NULL" );
    00126                 return payload;
    00127         }
    00128
    00132         T &operator*() {
    00133                 bdm_assert_debug ( payload, "dereferencing NULL" );
    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" );
    00150                 return payload;
    00151         }
    00152
    00156         const T &operator*() const {
    00157                 bdm_assert_debug ( payload, "dereferencing NULL" );
    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 {
    00257 public:
    00263         object_ptr() : shared_ptr<T> ( new T() ) { }
    00264
    00270         object_ptr ( const shared_ptr<T> &b ) : shared_ptr<T> ( b ) {
    00271                 bdm_assert_debug ( this->get(), "object_ptr cannot be empty" );
    00272         }
    00273
    00278         object_ptr ( T *p ) : shared_ptr<T> ( p ) {
    00279                 bdm_assert_debug ( p, "object_ptr cannot be empty" );
    00280         }
    00281
    00285         object_ptr<T> &operator= ( const object_ptr<T> &other ) {
    00286                 shared_ptr<T>::operator= ( other );
    00287                 return *this;
    00288         }
    00289 };
    00290
    00291 #define SHAREDPTR(class_name) typedef bdm::object_ptr< class_name > class_name##_ptr
    00292
    00293 #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
    00294
    00295 }
    00296
    00297 #endif