Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stand-alone shared_ptr<T> implementation?

Tags:

c++

shared-ptr

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?


Note:

"Standalone implementation of shared_ptr" means shared_ptr itself needs to be standalone.
Not just the including library.

So please, no Boost!

like image 339
user541686 Avatar asked Aug 29 '11 08:08

user541686


5 Answers

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.

like image 71
Mankarse Avatar answered Nov 04 '22 21:11

Mankarse


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.

like image 38
PatchyFog Avatar answered Nov 04 '22 21:11

PatchyFog


You can use Boost BCP to extract components from Boost.

like image 3
Georg Fritzsche Avatar answered Nov 04 '22 22:11

Georg Fritzsche


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.

like image 2
user541686 Avatar answered Nov 04 '22 21:11

user541686


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.

like image 2
David Given Avatar answered Nov 04 '22 20:11

David Given