Boost logo

Boost :

From: David B. Held (dheld_at_[hidden])
Date: 2003-01-30 02:17:09


"Andrei Alexandrescu" <andrewalex_at_[hidden]> wrote in message
news:b1aact$imm$1_at_main.gmane.org...
> [...]
> I suggest we just make an explicit function acquire() for the ownership
> policy and have all of its other member functions assume acquire() was
> called.

Unfortunately, this requires no-throw default construction of all policies.
Since ref_counted allocates the count even in the default case, we have
to silence any std::bad_alloc's that get thrown. That leaves us with
checking if we actually have a count or not. We either have to validate
the count pointer in every member function, or call a special function that
does nothing but check to see if ownership_policy() was successful or
not. Can we say 'ugly'?? Let me state the problem in C++:

smart_ptr(P p)
    : storage(), ownership(), conversion(), checking()
{
    try
    {
        storage::acquire(p);
        ownership::acquire(p);
        checking::on_init(p);
    }
    catch (...)
    {
        storage::destroy();
    }
}

If ownership() throws, p is leaked. So we have to make ownership() no-
throw:

ref_counted()
    : pCount(0)
{ }

ref_counted(P p)
    : pCount(new int(1))
{ }

void acquire(P p)
{
    if (pCount) throw 0;
    pCount = new int(1);
}

P clone(P p)
{
    if (!pCount) throw 0;
    ++*pCount;
    return p;
}

bool release(P p)
{
    if (!pCount) throw 0;
    if (!--*pCount)
    {
        delete pCount;
        return true;
    }
    return false;
}

friend inline unsigned use_count(ref_counted const& p)
{ if (!p.pCount) throw 0; return *(p.pCount); }

Or, we could do it this way:

ref_counted()
    : pCount(new (std::no_throw) int(1))
{ }

void acquire(P p)
{
    if (!pCount) throw 0;
}

And then mandate that ownership_policy is not usable until acquire()
has been called, avoiding further checks for pCount == 0. Hopefully,
requiring all no-throw default c'tors will not impose an undue penalty
on policies.

Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk