- 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
    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:
    00043         shared_ptr() :
    00044                         payload ( 0 ),
    00045                         refCnt ( 0 ) {
    00046         }
    00047
    00054         shared_ptr ( T *p ) :
    00055                         payload ( p ),
    00056                         refCnt ( p ? new unsigned ( 1 ) : 0 ) {
    00057         }
    00058
    00061         shared_ptr ( const shared_ptr<T> &other ) :
    00062                         payload ( other.payload ),
    00063                         refCnt ( other.refCnt ) {
    00064                 add_ref();
    00065         }
    00066
    00069         template<typename U>
    00070         shared_ptr ( const shared_ptr<U> &other ) :
    00071                         payload ( other.payload ),
    00072                         refCnt ( other.refCnt ) {
    00073                 add_ref();
    00074         }
    00075
    00076         ~shared_ptr() {
    00077                 del_ref();
    00078         }
    00079
    00080         shared_ptr<T> &operator= ( const shared_ptr<T> &other ) {
    00081                 other.add_ref();
    00082                 del_ref();
    00083
    00084                 payload = other.payload;
    00085                 refCnt = other.refCnt;
    00086
    00087                 return *this;
    00088         }
    00089
    00092         T *get() {
    00093                 return payload;
    00094         }
    00095
    00099         T *operator->() {
    00100                 it_assert_debug ( payload, "dereferencing NULL" );
    00101                 return payload;
    00102         }
    00103
    00107         T &operator*() {
    00108                 it_assert_debug ( payload, "dereferencing NULL" );
    00109                 return *payload;
    00110         }
    00111
    00114         const T* get() const {
    00115                 return payload;
    00116         }
    00117
    00121         const T *operator->() const {
    00122                 it_assert_debug ( payload, "dereferencing NULL" );
    00123                 return payload;
    00124         }
    00125
    00129         const T &operator*() const {
    00130                 it_assert_debug ( payload, "dereferencing NULL" );
    00131                 return *payload;
    00132         }
    00133
    00134         bool unique() const {
    00135                 return refCnt && ( *refCnt == 1 );
    00136         }
    00137
    00138         long use_count() const {
    00139                 return refCnt ? *refCnt : 0;
    00140         }
    00141
    00142         operator bool() const {
    00143                 return payload;
    00144         }
    00145
    00146         void swap ( shared_ptr &other ) {
    00147                 std::swap ( payload, other.payload );
    00148                 std::swap ( refCnt, other.refCnt );
    00149         }
    00150
    00151 private:
    00152         void add_ref() const {
    00153                 if ( refCnt ) {
    00154                         if ( *refCnt == UINT_MAX ) {
    00155                                 throw std::overflow_error (
    00156                                     std::string ( "Shared pointer has too many references." ) );
    00157                         }
    00158
    00159                         ++*refCnt;
    00160                 }
    00161         }
    00162
    00163         void del_ref() {
    00164                 if ( refCnt ) {
    00165                         if ( ! ( --*refCnt ) ) {
    00166                                 delete payload;
    00167                                 delete refCnt;
    00168                         }
    00169                 }
    00170         }
    00171 };
    00172
    00174 template<typename T, typename U>
    00175 bool operator== ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
    00176         return a.get() == b.get();
    00177 }
    00178
    00180 template<typename T, typename U>
    00181 bool operator!= ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
    00182         return a.get() != b.get();
    00183 }
    00184
    00186 template<typename T, typename U>
    00187 bool operator< ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
    00188         return a.get() < b.get();
    00189 }
    00190
    00198 template <typename T>
    00199 class object_ptr : public shared_ptr<T>
    00200 {
    00201 public:
    00207         object_ptr() : shared_ptr<T> ( new T() ) { }
    00208
    00214         object_ptr ( const shared_ptr<T> &b ) : shared_ptr<T> ( b ) {
    00215                 it_assert_debug ( this->get(), "object_ptr cannot be empty" );
    00216         }
    00217
    00222         object_ptr ( T *p ) : shared_ptr<T> ( p ) {
    00223                 it_assert_debug ( p, "object_ptr cannot be empty" );
    00224         }
    00225
    00226         object_ptr<T> &operator= ( const object_ptr<T> &other ) {
    00227                 shared_ptr<T>::operator= ( other );
    00228                 return *this;
    00229         }
    00230 };
    00231
    00232 #define SHAREDPTR(class_name) typedef bdm::object_ptr< class_name > class_name##_ptr
    00233
    00234 #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
    00235
    00236 }
    00237
    00238 #endif