
Interesting! I'll have to play with this - One issue that thwarted a lot of attempts at a better move library were classes that use type erasure. For example - the explicit constructors for adobe::any_regular_t (similar to boost any) look like this: template <typename T> explicit any_regular_t(const T& x, typename copy_sink<T>::type = 0) { ::new (storage()) typename traits<T>::model_type(x); } template <typename T> explicit any_regular_t(T x, typename move_sink<T>::type = 0) { ::new (storage()) typename traits<T>::model_type(move(x)); } The move_sink and copy_sink distinguish between movable and non- movable types. There were several solutions that relied on wrapper types that failed because T would be deduced as the wrapper type - I have no idea if that's an issue here but thought I'd point out the issue. If you're looking for a large test case you might try replacing the move library for ASL and see what happens - we have many test cases that verify move is working correctly. Sean On Feb 18, 2009, at 9:11 AM, David Abrahams wrote:
on Tue Feb 17 2009, Ion GaztaƱaga <igaztanaga-AT-gmail.com> wrote:
Hi to all,
I've uploaded a new version of the move emulation library to sandbox. I've put it temporarily in "move_semantics" folder to avoid overwriting current move code.
I've put some quickbook documentation whose introduction is based in the article "A Brief Introduction to Rvalue References" by Hinnant, Stroustrup, Kozicki.
http://svn.boost.org/svn/boost/sandbox/libs/move_semantics/index.html
The library needs specially modified Interprocess containers (and Intrusive because of dependences), which I've also uploaded to sandbox. The examples show how movable only values can be inserted into containers.
For those that don't like svn sandbox (I'm one of them) I've also put the code and the documentation here:
http://www.drivehq.com/web/igaztanaga/move_semantics.zip
And online documentation also here:
Wow, this is way cool: you've found a way to allow the default copy ctor and assignment operators to be in place, and yet still treat rvalues specially! I guess that's because overloading prefers derived classes:
template <class B> struct D : B {};
template <class T> struct B { operator D<B>&() { return *static_cast<D<B>* >(this); }
B() {}
B(B const&) // move ctor { T::copy_ctor_called(); }
B(D<B>& x) // move ctor { }
};
B<int> f() { return B<int>(); } // <== most likely elided; otherwise move B<int> x(f()); // <== calls move ctor B<int> y(x); // <== calls copy ctor, generating error
So you're relying on a wee bit of undefined behavior by downcasting your B&, but that's alright with me.
The one thing I guess you give up when doing things this way is the ultimate efficiency of copy elision for incoming parameters. However, we can tell people that when they're going to copy the rhs anyway, they should pass by value. That means
self& operator=(self rhs) { swap(*this,rhs); return *this; }
should still be the canonical assignment operator (if your docs can rely on universally-benign undefined behavior, surely they can also rely on universally-implemented copy elision).
Hmm, and does this work?
template <class T> struct C : B<T> { operator D<C>&(); C(D<C>& rhs); C(); };
int g(B<int> const&); int test = g(C<int>());
Yes! Pretty slick.
The documentation is not in english, it's in my own english dialect so be careful when reading ;-) Patches and corrections welcome. I've documented some functions to create a little boostbook reference.
I've invested some precious time in the library and testing different approaches to see if it plays well with containers but I would like to hear some comments on whether the direction is acceptable and if I should spend more time on it.
Oh, yeah, you definitely should. I think Howard has a move semantics test suite we can throw at this library. Howard?
If someone else with more time wants to continue the library, please do it! ;-)
I've personally added to the library all that I've seen useful for move-aware containers, so it might lack some features (move aware algorithms, for example).
Jah; those'll come in time.
Anyway, my opinion is that we need some move library, better now than later even if it's too basic, so that we can unify all redundant move emulation that we already have in boost libraries. I hope this is a step in the right direction.
I like this, very very much. It's so clean and obvious that it even worries me a little: didn't I try and discard this approach once? I dunno, but if we can get it to pass a rigorous test suite, I think it's totally awesome.
-- Dave Abrahams BoostPro Computing http://www.boostpro.com