Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-04-12 10:01:28


I have to stop playing with this stuff and get back to work now, but
over the weekend I started a library that allows a "reasonably
convenient, useful amount" of move semantics. Many compilers
implement enough (N)RVO that implicit moving from rvalues is
unneccessary, and those seem to coincide roughly with the compilers
where we have to internally shut off some capability because of the
compiler's interpretation of 8.5.3/5 (**). So it seems you can pretty
much eliminate all needless copies.

Here's what you can do with the current state of the move library,
which supplies macros (eeeeew!) to avoid code duplication:

struct X
  : boost::movable<X>
{
    BOOST_LVALUE_COPY_CTOR(
        X, (rhs)(: initializers...),
    {
        // copy ctor body
    })

    BOOST_LVALUE_ASSIGN(
        X, (rhs),
    {
        // copy assign body
    })
    
    X(move_from<X> rhs)
    {
        // move ctor logic
    }

    X& operator=(move_from<X> rhs)
    {
        // move assign logic
    }
};

boost::movable<X> just encapsulates the conversion to move_from<X> and
makes the copy ctor/assignment private, so you can always replace it
with a written-out conversion to move_from<X> if you don't like the
"MI non-EBO" (or other) impact of library-mandated inheritance.

This work owes inspiration to Rani Sharoni's "improved auto_ptr"
(http://tinyurl.com/2rxpj) and of course one must acknowledge Andrei
Alexandrescu for being crazy enough to even try doing this in a
library in the first place (Mojo). Eric Friedman had an earlier
boost/move.hpp in the sandbox based on Mojo (which I replaced with his
permission), and I adapted his tests, in addition to my own, to work
with the new code.

It might make sense to use this library to optimize selected Boost
components; shared_ptr, any, and dynamic_bitset come to mind, just off
the top of my head.

You can find the code in boost/move.hpp and tests in
libs/move/test/*.cpp. It "basically works" with all MSVC versions,
Borland, gcc-2.95, gcc-3.3.1, comeau (strict warnings mode only, until
I find out how to detect that we're in strict errors mode), and all
intel-win32 versions. I don't know how to make gcc-3.2 work yet.
The places where it fails, certain things seem to compile which one
would prefer to cause an error.

Enjoy,
Dave

(**) see http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html

-- 
Dave Abrahams
Boost Consulting
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