[ create a new paste ] login | about

Link: http://codepad.org/MirlNayf    [ raw code | output | fork ]

C++, pasted on May 20:
#include <cstddef>

template <typename T>
struct smart_ptr_wrapper {
   T* raw_pointer;
   size_t strong_count;
   size_t weak_count;

   // Should be used if wrapper is constructed from
   // shared pointer
   smart_ptr_wrapper(T* raw_pointer) : 
      raw_pointer(raw_pointer), strong_count(0), weak_count(0)
      { }
   
   void dispose_wrapped_object() {
      delete raw_pointer;
   }
};

#define SHARED_PTR_FRIEND_DECLARATIONS \
   template <typename Z> friend class weak_ptr; \

// Shared pointer implementation
template <typename T>
class shared_ptr {
   // Declare friend smart pointer classes
   SHARED_PTR_FRIEND_DECLARATIONS

private:
   // Shared wrapper implementation
   typedef smart_ptr_wrapper<T> shared_ptr_wrapper;
   shared_ptr_wrapper* wrapper;

private:
   // Shared wrapper additional routines
   void increase_reference_count() {
      ++(wrapper->strong_count);
   }
   void decrease_reference_count() {
      --(wrapper->strong_count);

      if (wrapper->strong_count == 0) {
         wrapper->dispose_wrapped_object();
      }
      // Dispose the wrapper if there are no more
      // references to this object
      // @note This should actually lock the wrapper to
      // preserve thread safety
      if (wrapper->strong_count == 0 && wrapper->weak_count == 0) {
         delete wrapper;
      }
   }

public:
   // Default constructor to grant syntax flexibility
   explicit shared_ptr(T* pointer = NULL) : wrapper(new shared_ptr_wrapper(pointer)) {
      increase_reference_count();
   }

   shared_ptr(const shared_ptr& p) : wrapper(p.wrapper) {
      increase_reference_count();
   }

   shared_ptr& operator= (shared_ptr& p) {
      // Set new reference counts
      decrease_reference_count();
      p.increase_reference_count();
      // Set new wrapper
      wrapper = p.wrapper;

      return *this;
   }

   ~shared_ptr() {
      decrease_reference_count();
   }

   // @todo
   // void swap(...)
   // void set(...) or reset(...)

   T* get        () const { return  wrapper->raw_pointer; }
   T* operator-> () const { return  get(); }
   T& operator*  () const { return *get(); }

   // User comparison operation
   operator void* () const {
      return (get() == NULL);
   }
};

template <typename T>
class weak_ptr {
private:
   // Weak wrapper implementation
   // Weak wrapper implementation
   typedef smart_ptr_wrapper<T> weak_ptr_wrapper;
   weak_ptr_wrapper* wrapper;

private:
   // Shared wrapper additional routines
   void increase_reference_count() {
      ++(wrapper->weak_count);
   }
   void decrease_reference_count() {
      --(wrapper->weak_count);

      // Dispose the wrapper if there are no more
      // references to this object
      // @note This should actually lock the wrapper to
      // preserve thread safety
      if (wrapper->strong_count == 0 && wrapper->weak_count == 0) {
         delete wrapper;
      }
   }

public:
   // Default constructor to grant syntax flexibility
   weak_ptr() : wrapper(NULL) { }

   weak_ptr(const shared_ptr<T>& pointer) : wrapper(pointer.wrapper) {
      increase_reference_count();
   }

   weak_ptr(const weak_ptr& p) : wrapper(p.wrapper) {
      increase_reference_count();
   }

   weak_ptr& operator= (weak_ptr& p) {
      // Set new reference counts
      // @note If this is 'just-a-pointer', which was created
      // using default constructor then our wrapper would be 'NULL'
      if (wrapper != NULL) {
         decrease_reference_count();
      }
      p.increase_reference_count();
      // Set new wrapper
      wrapper = p.wrapper;

      return *this;
   }

   ~weak_ptr() {
      decrease_reference_count();
   }

   // @todo
   // void swap(...)

   // @note Actually should be 'lock' instead of simply get
   // to preserve thread safety

   /*
      @deprecated

         T* get () const {
            size_t reference_count = wrapper->reference_count;
            size_t dummy_reference_count = wrapper->pointer.wrapper->reference_count;

            // If our object has no actual strong references left, we
            // return NULL, because the actual object should be destroyed
            // at this point

            // @note Actually, object will be disposed when there are no WEAK references
            // to it left. Still this way of memory management is the only way to check
            // whether the object actually exists at the 'get' call moment.
            // 
            // What we could achieve here in terms of 'fast' response would be object disposing
            // right after the first wrong 'get' call. Yet this would require more code and 
            // therefore (because I see no actual benefit in that approach) isn't done..
            return (dummy_reference_count >= reference_count) ? NULL : wrapper->pointer.get();
         }
   */

   T* get() const { return (wrapper->strong_count == 0) ? NULL: wrapper->raw_pointer; }
   T* operator-> () const { return  get(); }
   T& operator*  () const { return *get(); }

   // User comparison operation
   operator void* () const {
      return (get() == NULL);
   }
};

int main() {

   shared_ptr<int> sp1(new int(4));
   weak_ptr<int> wp1(sp1);
   wp1 = weak_ptr<int>(sp1);
   return 0;
}


Output:
1
2
3
In function 'int main()':
Line 189: error: no match for 'operator=' in 'wp1 = weak_ptr<int>(((const shared_ptr<int>&)((const shared_ptr<int>*)(& sp1))))'
compilation terminated due to -Wfatal-errors.


Create a new paste based on this one


Comments: