Instantly share code, notes, and snippets.
Created
June 6, 2012 03:14
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save murphybytes/2879649 to your computer and use it in GitHub Desktop.
Had to roll my own shared pointer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __SHARED_PTR_HPP__ | |
#define __SHARED_PTR_HPP__ | |
#include <string> | |
#include <sstream> | |
using std::string; | |
using std::stringstream; | |
namespace ucp { | |
template< class T > class shared_ptr { | |
public: | |
typedef T* pointer_t; | |
typedef T& reference_t; | |
typedef const reference_t const_reference_t; | |
typedef unsigned int reference_counter_t; | |
typedef T const * const const_pointer_t; | |
typedef reference_counter_t* reference_counter_pointer_t; | |
typedef pointer_t& reference_pointer_t; | |
private: | |
reference_counter_pointer_t reference_count_; | |
pointer_t shared_pointer_; | |
reference_counter_t inc() { | |
reference_counter_t count = 0; | |
if( reference_count_ ) { | |
++(*reference_count_); | |
count = *reference_count_; | |
} | |
return count; | |
} | |
reference_counter_t dec() { | |
reference_counter_t count = 0; | |
if( reference_count_ ) { | |
--(*reference_count_); | |
count = *reference_count_; | |
} | |
if( 0 == count ) { | |
delete shared_pointer_; | |
shared_pointer_ = 0; | |
delete reference_count_; | |
reference_count_ = 0; | |
} | |
return count; | |
} | |
public: | |
shared_ptr( ) | |
:shared_pointer_(0), reference_count_( 0 ) { | |
} | |
template< class U > | |
explicit shared_ptr( U* u ) | |
:shared_pointer_(u), reference_count_(new reference_counter_t(1)) { | |
} | |
shared_ptr( shared_ptr const& sp ) | |
:shared_pointer_(sp.shared_pointer_), reference_count_(sp.reference_count_) { | |
inc(); | |
} | |
template< class U > | |
shared_ptr( shared_ptr< U > const& u ) | |
:shared_pointer_( u.shared_pointer_ ), reference_count_( u.reference_count_ ) { | |
inc(); | |
} | |
~shared_ptr() { | |
dec(); | |
} | |
operator void*() const { return shared_pointer_; } | |
pointer_t get() const { | |
return shared_pointer_; | |
} | |
shared_ptr& operator=( const shared_ptr& sp ) { | |
if( shared_pointer_ != sp.shared_pointer_ ) { | |
dec(); | |
} | |
shared_pointer_ = sp.shared_pointer_; | |
reference_count_ = sp.reference_count_ ; | |
inc(); | |
return *this; | |
} | |
reference_t operator*() { | |
return *shared_pointer_; | |
} | |
const_reference_t operator*() const { | |
return *shared_pointer_; | |
} | |
pointer_t operator->() { | |
return shared_pointer_; | |
} | |
pointer_t operator->() const { | |
return shared_pointer_; | |
} | |
/** | |
* For diagnosics only | |
*/ | |
string to_string() { | |
stringstream ss; | |
ss << "shared_ptr reference count: " << reference_count() << " pointer address: " << shared_pointer_ ; | |
return ss.str(); | |
} | |
reference_counter_t reference_count() const { | |
reference_counter_t count = 0; | |
if( reference_count_ ) { | |
count = *reference_count_; | |
} | |
return count; } | |
}; | |
template< class U, class V > | |
bool operator==( shared_ptr< U > const & u, shared_ptr< V > const& v ) { | |
return u.get() == v.get(); | |
} | |
template< class U, class V > | |
bool operator!=( shared_ptr< U > const& u, shared_ptr< V > const& v ) { | |
return u.get() != v.get(); | |
} | |
template< class U, class V > | |
bool operator<( shared_ptr< U > const& u, shared_ptr< V > const& v ) { | |
return u.get() < v.get(); | |
} | |
} | |
#endif | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment