Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2002-09-27 07:57:11


From: "Fernando Cacciola (hotmail)" <fernando_cacciola_at_[hidden]>

> Hi,
>
> Consider this example of "synchronized multiple updates"

Good choice of problem. Most people never consider how the operations on
sub-parts of their system affect the overall exception guarantees. I treat
this sort of thing in
http://www.boost.org/more/generic_exception_safety.html.

> (I'll show some details so I can focus
> on a solution applicable to cases when both
> sequences cannot be merged or associated intrusively.
> Ownership issues are left out, so bare pointers are used)
>
>
> class InterfacedMultiPolygon
> {
> MultiPolygon mpoly_ ; // sequence 1
>
> std::vector<PolygonInterface> interfaces_ ; // sequence 2
>
> void push_back ( Polygon* poly, PolygonInterface* intf )
> {
> // Both sequences must be synchronized.
> mpoly_ .push_back(poly);
> interfaces_.push_back(intf);
> }
> } ;
>
> The goal is to achieve the basic guarantee for the synchronized
push_back.
>
> How would you do this?
> (Without copying the whole thing just to move the final state at the end,
of
> course)
>
> The only thing I could think of is to reserve storage for both containers
> before the push_back:
>
>
>
> void push_back ( Polygon* poly, PolygonInterface* intf )
> {
> // Exceptions can be thrown below...
> mpoly_.reserve( mpoly_.size() + 1);
> interfaces_.reserve(interfaces_.size()+1);
>
> // But no exceptions can be thrown after this point.
> mpoly_ .push_back(poly);
> interfaces_.push_back(intf);
> }

This only works because the copy-constructors of your element types don't
throw. A general solution needs a try/catch or other cleanup mechanism:

    {
        vector1.push_back(e1);
        try {
            vector2.push_back(e2):
        }
        catch(...) {
            vector1.pop_back();
            throw;
        }
    }

And now you have not only the basic, but the strong guarantee (unless you
consider the capacity() of vector1 to be part of the visible state of the
composite container).

> w.r.t to the containers (assuming that the transfers are "basically
> exception safe"),

??? What does this mean?

> does the technique of reserving storage always provide the basic
guarantee?

Clearly not.

> Is the problem generic enough?

I guess not.

> Is the solution good enough?

Depends on your requirements.

-----------------------------------------------------------
           David Abrahams * Boost Consulting
dave_at_[hidden] * http://www.boost-consulting.com


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