libqi-api
2.0.6.8
|
00001 #pragma once 00002 /* 00003 * Copyright (c) 2012 Aldebaran Robotics. All rights reserved. 00004 * Use of this source code is governed by a BSD-style license that can be 00005 * found in the COPYING file. 00006 */ 00007 00008 00009 #ifndef _QI_SHARED_PTR_HPP_ 00010 #define _QI_SHARED_PTR_HPP_ 00011 00012 #include <qi/atomic.hpp> 00013 #include <qi/log.hpp> 00014 00015 namespace qi 00016 { 00018 template <typename T> 00019 class SharedPtr 00020 { 00021 public: 00023 SharedPtr(T *ptr) 00024 : _ptr(ptr) 00025 , _refcount(new qi::Atomic<int>(1)) 00026 { 00027 } 00028 00031 ~SharedPtr() 00032 { 00033 if (--(*_refcount) == 0) 00034 { 00035 delete _ptr; 00036 delete _refcount; 00037 } 00038 } 00039 00041 SharedPtr(const SharedPtr<T> &sp) 00042 { 00043 /* 00044 * Note that this line is racy. 00045 * If someone is deleting _refcount, 00046 * it cannot be used below. 00047 */ 00048 if (++(*sp._refcount) != 1) 00049 { 00050 _ptr = sp._ptr; 00051 _refcount = sp._refcount; 00052 } 00053 else 00054 { 00055 00056 _ptr = 0; 00057 _refcount = 0; 00058 qiLogDebug("qi.log.shared_ptr") 00059 << "tried to copy a shared pointer targeted for deletion" 00060 << std::endl; 00061 } 00062 } 00063 00066 SharedPtr& operator=(SharedPtr<T> &sp) 00067 { 00068 // release the current pointer 00069 if (--(*_refcount) == 0) 00070 { 00071 delete _ptr; 00072 delete _refcount; 00073 } 00074 if (++(*sp._refcount) != 1) 00075 { 00076 _ptr = sp._ptr; 00077 _refcount = sp._refcount; 00078 } 00079 else 00080 { 00081 qiLogDebug("qi.log.shared_ptr") 00082 << "tried to copy a shared pointer targeted for deletion" 00083 << std::endl; 00084 } 00085 return *this; 00086 } 00087 00089 T &operator*() const 00090 { 00091 return *_ptr; 00092 } 00093 00095 T *operator->() const 00096 { 00097 return _ptr; 00098 } 00099 00100 private: 00101 T *_ptr; 00102 qi::Atomic<int> *_refcount; 00103 }; 00104 } 00105 00106 #endif // _QI_SHARED_PTR_HPP_