Does anyone know of an open-source, standalone implementation of TR1 shared_ptr
(and maybe other smart pointers) that I can use in my programs?
"Standalone implementation of shared_ptr
" means shared_ptr
itself needs to be standalone.
Not just the including library.
So please, no Boost!
The boost implementation of shared_ptr
is entirely header-only, so installing boost to use it is as simple as downloading boost and adding it to your compiler's header search paths. This is no harder with boost than with any other stand-alone implementation. If you want to extract just the shared_ptr
component to make a separate distribution, then you can use Boost BCP.
You can hack the sharedptr.h header in wxWidgets pretty easily to remove the few macro dependencies (assert, "explicit" keyword, etc.). You then need to replace or remove the atomic inc/dec of the internal reference counting variable. Rename the template and stick it in a namespace. Then you'll have a single-file stand-along version of shared_ptr.
This has the advantage that the source you are modifying has had some wide usage and peer review.
You can use Boost BCP to extract components from Boost.
Huh, I guess something I made myself might be even better than shared_ptr
:
template<typename T>
class auto_
{
T *pValue;
mutable const auto_<T> *pPrev, *pNext;
public:
auto_() : pValue(new T()), pPrev(NULL), pNext(NULL) { }
auto_(T *pValue) : pValue(pValue), pPrev(NULL), pNext(NULL) { }
auto_(const T &v) : pValue(new T(v)), pPrev(NULL), pNext(NULL) { }
auto_(const auto_<T> &o) : pValue(o.pValue), pPrev(&o), pNext(NULL)
{ o.pNext = this; }
virtual ~auto_()
{
const auto_<T> *const pPrev = this->pPrev, *const pNext = this->pNext;
if (pPrev != NULL) { pPrev->pNext = pNext; }
if (pNext != NULL) { pNext->pPrev = pPrev; }
if (pPrev == NULL && pNext == NULL) { delete this->pValue; }
this->pPrev = this->pNext = NULL;
this->pValue = NULL;
}
auto_<T>& operator=(const auto_<T>& other)
{
if (this != &other)
{
this->~auto_();
this->pValue = other.pValue;
this->pPrev = &other;
this->pNext = other.pNext;
if (other.pNext != NULL) { other.pNext->pPrev = this; }
other.pNext = this;
}
return *this;
}
operator T&() { return *this->pValue; }
operator T*() { return this->pValue; }
T* operator->() { return this->pValue; }
T& operator *() { return *this->pValue; }
operator const T&() const { return *this->pValue; }
operator const T*() const { return this->pValue; }
const T* operator->() const { return this->pValue; }
const T& operator *() const { return *this->pValue; }
};
Sample usage:
template<typename T>
T recurse(T value, int depth)
{
if (depth > 0) { T result = recurse(value, depth - 1); return result; }
else { return value; }
}
auto_<int> test()
{
printf("Value: %d\n", *recurse(auto_<int>(10), 3));
auto_<int> p1 = recurse<auto_<int> >(5, 3);
printf("Value: %d\n", *p1);
auto_<int> p2 = 3;
p1 = p2;
p2 = p1;
return p2;
}
It looks easier to use than shared_ptr
, IMHO.
Does it have any pitfalls which I missed (aside from the obvious thread-unsafety)?
Any (constructive) criticism appreciated.
I've been looking for such a thing myself --- like you, I have a project where including huge wads of Boost is totally unacceptable.
I've found this:
http://www.lri.fr/~marc/EO/eo/doc/html/shared__ptr_8h-source.html
I have no idea of the code quality, as it's GPL2 which means I can't use it in my proprietary code, but it seems to have no dependencies. But it does seem to be an answer to your question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With