Boost logo

Boost :

From: Fernando Cacciola \(hotmail\) (fernando_cacciola_at_[hidden])
Date: 2002-09-27 07:58:33


Hi,

Consider this example of "synchronized multiple updates"

(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);
}

w.r.t to the containers (assuming that the transfers are "basically
exception safe"),
does the technique of reserving storage always provide the basic guarantee?
Is the problem generic enough?
Is the solution good enough?

If so, we could package the technique as an idiom:

// ensure_room(cont,n)
//
// Makes sure that *after the call* there is enough room in
// the container "cont" so that subsequent insertion of
// "n" elements won't cause any allocations.
// Thus, you can expect exceptions to be thrown
// during "ensure_room" but not during element insertion.
//
template <class Cont>
void ensure_room ( Cont& c, typename Cont::size_type n =1 )
{ c.reserve(c.size() + n ) ; }

void push_back ( Polygon* poly, PolygonInterface* intf )
{
  ensure_room(mpoly_,1);
  ensure_room(interfaces_,1);

  mpoly_ .push_back(poly);
  interfaces_.push_back(intf);
}

How do you like 'ensure_room' in utilities?

Fernando Cacciola


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