Boost logo

Boost :

From: Hamish Mackenzie (boost_at_[hidden])
Date: 2002-02-06 20:17:46

I have had a crack at a possible boost/move.hpp

On Wed, 2002-02-06 at 20:56, Sean Parent wrote:
> on 2/5/02 4:40 PM, Howard Hinnant at hinnant_at_[hidden] wrote:
> > I think I misstated my goal. I'm hoping that containers will be able to
> > detect and use move semantics as an internal optimization, not effecting
> > the container's interface.
> Sorry - I had viewed this as a splinter to the thread on doing an
> auto_ptr_vector, which I had suggested become generalized to support any
> object that doesn't support copy semantics but does support some combination
> of move / swap.
> It was correctly pointed out, that swap can be implemented using
> constructing moves (in the same way it is done with copying, through a
> temp). But in the case of a non-POD class, I don't think this is a win
> unless you define the source from the move to have been destructed as a
> result of the move (call this relocate).
> The move vs. relocate semantics would be:
> move - moving a source A into uninitialized memory B. The result leaves A in
> an indeterminate but destructible state. "Copy" construction of an auto_ptr
> is an example.

See move_construct( A, B )
aka move_to_construct( A ) = move_from( B )

> relocate - moving a source A into uninitialized memory B. The result leaves
> A in a destructed state. Requires the source A is also managed with
> placement new and delete.

See move_construct_destroy( A, B )
aka move_to_construct( A ) = move_from_destroy( B )
> The relocate construct would be useful for container optimization - but I
> think the complexities of implementing it for anything that can't be treated
> as a POD (just do a memcopy for the relocate) is difficult. It may be worth
> having a trait though for objects that can use memcopy to relocate.
> The first item, I think is simplest to implement using a non-throwing
> constructor (one that constructs an object upon which the only valid
> operation is destruction) and a swap. That's not to say that this is how you
> would have to implement it- however there are many existing classes that
> would meet these requirements. So let's define move as:
> template <class T>
> T* safe_construct(void* placement) throw()
> {
> return new(placement)T(std::nothrow);
> }

Using std::nothrow a nice idea and coupled with something Howard pointed

How about instead of nothow we create

class move_use_swap_type {};

If the class designer creates a constructor and swap function like so

class x
  x( boost::move_use_swap ) throw() {}
  void swap( x & ) throw() {}

swap( x & a, x & b ) throw() { a.swap( b ); }

We can then use is_convertable< boost::move_use_swap, T >::value to
select move_traits< x > so that it uses swap (and passes move_use_swap()
to the constructor).

Hopefuly the name move_use_swap will be enough to remind them to write
the swap function.

> template <class T>
> T* move(void* placement, T& x) throw()
> {
> T* result (safe_construct<T>(placement));
> std::swap(*result, x);
> return result;
> }
> Specializations can be provided for either safe construction and/or move and
> an is_movable trait can be added to the trait library. For items that are
> movable, I think you can change the exception guarantee from basic to
> transactional without a performance penalty in the non-exception case in the
> std containers (assuming they are re-implemented of course). You can also
> build containers (or provide an extended interface to the existing
> containers) for types that only support move and not copy operations (like
> auto_ptr).

Check out move_traits in move.hpp. And let me know your thoughts. I
have a few changes to make on it based on discussion with Howard (eg.
the default specialization for move_traits is going to derive from a
move_traits_no_move class preventing moves by default).

Hamish Mackenzie

Boost list run by bdawes at, gregod at, cpdaniel at, john at