[Boost-bugs] [Boost C++ Libraries] #1910: function::swap should avoid doing memory allocations

Subject: [Boost-bugs] [Boost C++ Libraries] #1910: function::swap should avoid doing memory allocations
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2008-05-10 13:01:48

#1910: function::swap should avoid doing memory allocations
 Reporter: niels_dekker | Owner: dgregor
     Type: Bugs | Status: new
Milestone: Boost 1.36.0 | Component: function
  Version: Boost 1.35.0 | Severity: Problem
 Keywords: |
 This ticket was triggered by a posting from Arvid Norberg,
 boost::function<>::swap() can throw]. He was surprised to see that
 {{{boost::function::swap}}} can throw an exception, in case of a memory
 allocation failure. And he also remarked that TR1's {{{function::swap}}}
 is specified ''not'' to throw.

 The current {{{function::swap}}}
 function_template.hpp, from trunk revision 43884]) is implemented by doing
 three copy operations:
     void swap(BOOST_FUNCTION_FUNCTION& other)
       if (&other == this)

       BOOST_FUNCTION_FUNCTION tmp = *this;
       *this = other;
       other = tmp;

 I think that a major cause of exceptions can be taken away, by having
 {{{function::swap}}} implemented by means of ''moving'', instead of

     void swap(BOOST_FUNCTION_FUNCTION& other)
       if (&other == this)


 This new {{{boost::function::move_assign}}} member function would in most
 cases just copy the function object held by its argument to {{{*this}}},
 just like {{{boost::function}}}'s copy assignment operator does. But if
 the argument would hold its function object within a buffer ''allocated on
 the heap'', {{{move_assign}}} would pass the buffer to {{{*this}}}, and
 set the argument's buffer pointer to {{{NULL}}}.

 The patch has {{{boost::function::move_assign}}} added to
 Out of modesty, I declared {{{move_assign}}} as a ''private'' member
 function, but feel free to make it public. Moreover, it could be changed
 to move ''from'' {{{*this}}} ''to'' its argument (and renamed, e.g., to
 {{{move_to}}}), so that it would support moving a temporary ''(rvalue)''.
 But I think that's beyond the scope of this ticket...

 == Implementation details ==

 The attached patch has a boolean argument added to all {{{manage}}}
 functions, telling whether or not the buffer should be moved. Thereby,
 the implementation of {{{move_assign}}} is quite similar to the existing
 {{{assign_to_own}}}, having the same call to {{{f.vtable->manager}}}, but
 passing {{{true}}} as last argument.

 This boolean argument {{{move_buffer}}} is only relevant to the specific
 {{{manager}}} overload for function objects that require heap allocation,
 which does in the patched version of {{{function_base.hpp}}}:
   if (move_buffer)
     out_buffer.obj_ptr = in_buffer.obj_ptr;
     in_buffer.obj_ptr = 0;

 I made {{{obj_ptr}}} ''mutable'', to work around the fact that
 {{{in_buffer}}} is a ''const'' reference. Instead, I guess a
 {{{const_cast}}} could be used, but I didn't have the guts to do so. ;-)

Ticket URL: <http://svn.boost.org/trac/boost/ticket/1910>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:49:57 UTC