|
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
http://groups.yahoo.com/group/boost/files/move.tar.gz
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
out.
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
{
public:
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 acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk