From: Eric Friedman (ebf_at_[hidden])
Date: 2002-08-15 04:00:14


I've made an attempt at designing and implementing a nothrow move
mechanism, which, among other things, will serve vital to the
completion of the Boost.Variant library.

The code is in the sandbox:

  boost/move.hpp
  boost/auto_mover.hpp
  libs/move/auto_mover_test.cpp

Semantics for boost::move are as follows:

  // Moves the source object to the given storage, leaving the source
  // object in a consistent, yet unpredictable, state.
  //
  template <typename T>
  T * move(void * destination, T & source); // nothrow

The boost::move facility is extensible to user-defined types via
boost::move_traits class template, with the following semantics:

  template <> struct move_traits< UDT >
  {
      static void move(void * destination, UDT & source); // nothrow
  };

Note that the generic move_traits template handles the cases for T such
that boost::has_trivial_copy<T> or boost::has_nothrow_copy<T> are true,
in which an appropriate nothrow move_traits can be selected without
specialization from the user.

As well, a boost::is_moveable<T> class template provides a compile-time
determination as to whether objects of specified type T are moveable
(i.e., either an implicit or explicit move_traits specialization has
been provided).

Now to explain boost::auto_mover<T>. This class is an auto_ptr-esque
class that wraps objects of specified moveable type T. Its semantics
are very similar to auto_ptr, but the details would take too long to
explain here. I recommend those interested to take a look at the source
(until I develop documentation).

A neat use of boost::auto_mover is constant-time, stack-based, nothrow
return of std::string:

  #include "boost/auto_mover.hpp"
  #include <string>

  namespace boost {
      template <> struct move_traits< std::string >
      {
          static void move(void* dest, std::string& src)
          {
              std::string* p = new(dest) std::string; // nothrow
              p->swap(dest); // nothrow
          }
      };
  } // namespace boost (for specialization)

  boost::auto_mover<std::string> f()
  {
      std::string str("abcd");
      str += "efg";
      return boost::auto_mover<std::string>(str);
  }

Of course, there are numerous other uses of boost::auto_mover (in
expressing move semantics for noncopyable objects, for example).

Let me know what you think.

Thanks,
Eric Friedman