|
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