Boost logo

Boost :

From: Sean Parent (sparent_at_[hidden])
Date: 2002-02-05 18:24:14


----- Original Message -----
From: "Howard Hinnant" <hinnant_at_[hidden]>

> It is my wish that ultimately such a design could be merged into the
> existing std::containers (and other containers as well for that
> matter). In order for that to happen, the containers must be able to
> detect at compile time if a class supports move semantics, then the
> container could choose to use either move or copy semantics for things
> such as insert.

I don't think that is a plausible goal - the current containers assume
copying semantics in a number of places (insert, push_back, construction).
Even pop is designed with the notion that the user first retrieves a copy of
the last element with back (if needed). Pop doesn't return the last element
to avoid losing an element if an exception is thrown on the copy.

I do think it is reasonable to have standard traits for what types support
non-throwing swap and move construction. And specialize the standard
containers to be optimized for the cases where you have a type that supports
non-throwing swap and copy operation. to improve efficiency (and exception
handling). Possibly by implementing the copying container using the swapping
container.

The requirements, however, can't be met one in terms of the other (i.e., a
swap safe object is not necessarily copyable, and a copyable object may not
be swap safe).

I think the next step is to clearly define the requirements of swap and move
construction (and think through if those are sufficient primitives given
current language restrictions). It might be reasonable, for example, if you
are requiring a move construction that you allow for the requirement of a
non-throwing default constructor that would construct the object in an
indeterminate, but destructible, state. Any object that is in an
indeterminate state can still be swapped with another indeterminate object
or one in a valid state. If an object has an indeterminate state - then it
can be used as a default constructed state - and move _can_ be defined in
terms of a default construction and a swap...

template <class T>
void move_construct(void* destination, T& source)
{
    T* dest = new (destination) T(std::nothrow); // Using nothrow to
distinguish this from any other default constructor.
    std::swap(source, *dest);
}

A simple move is a destruct (placement delete) and a move construct.

The important item is to distill down a minimal meaningful set of
requirements.
Sean


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk