[move] Unifying move emulation code in boost

Hi, Howard's unique_ptr contribution has shown again the need for a unified move emulation in Boost. We already have move emulation at least in 5 libraries: -> Interprocess: based on sandbox boost.move library, return types are wrapped in a move_return type. -> Unordered: based on Adobe's move library. It's more advanced than the previous one, but Adobe's own library says (http://stlab.adobe.com/group__move__related.html) that a Movable type must satisfy the requirements of concept Regular, which has copy constructor (thus disabling move-only types!). I don't know if the move emulation itself uses Regular requirements. -> Thread: similar to Howard's unique_ptr move emulation code, user code never sees move_xxx or similar classes. -> Ptr_container: a simple emulation used for static_move_ptr, that could be replaced with a boost::unique_ptr class. -> Variant: MOJO-based emulation (similar to the one used by Interprocess). I think it can be easily replaced with unique_ptr-style emulation. We've been waiting the move library for months, but the fact is that we can't continue having ad-hoc solutions for each library. boost::thread objects must be stored somewhere and unordered containers and boost::interprocess containers are already move-aware. I want to make Intrusive also move-aware but I won't do it until there is some general consensus on what's the common move emulation. I think code changes in boost::thread and boost::unordered would be minimal if we adopt a solution similar to the one used by Howard's unique_ptr. Interprocess changes are heavier but I'm reading to adapt the library to that solution. I've written (attached) a small, surely not complete, but usable boost/move.hpp header (ok, it could go to boost/detail/move.hpp until a decent review is done) that is tested with a movable class in the file movable_test.cpp, both with Visual 7.1 and move-enabled GCC 4.3. The goal of this post is to know if that header file would be enough for all current libraries using move emulation. I have more suggestions (new traits like has_trivial_destructor_after_move<>...) but the main question is if that header can be used to agree a common protocol between us. It would be really nice if we could rework our code for Boost 1.39. If the header contains enough for everyone, I'm ready to write some documentation and tests. I know that this Move library is not what many expect (common macros and utilities to write the same code for rvalue-enabled and older compilers) but I'm afraid entropy has already grown too much ;-) and we can't continue waiting while we add more and more emulation code to Boost. Regards, Ion // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2007-8 Anthony Williams // (C) Copyright 2009 Howard Hinnant // (C) Copyright 2009 Ion Gaztanaga #include <boost/config.hpp> #include <boost/type_traits/is_convertible.hpp> #ifndef BOOST_HAS_RVALUE_REFS #ifndef BOOST_NO_SFINAE #include <boost/utility/enable_if.hpp> #endif #else //#ifndef BOOST_HAS_RVALUE_REFS #include <boost/type_traits/remove_reference.hpp> #endif namespace boost { #include <boost/config/abi_prefix.hpp> #ifndef BOOST_HAS_RVALUE_REFS template<class T> class rv { private: rv &operator=(const rv&); T& r_; public: explicit rv(T& r) : r_(r) {} T* operator->() {return &r_;} T& operator*() {return r_;} }; template<class T> class is_movable { public: static const bool value = boost::is_convertible<T&, rv<T> >::value; }; #ifndef BOOST_NO_SFINAE template<typename T> typename boost::enable_if<boost::is_movable<T>, T>::type move(T& t) { return T(rv<T>(t)); } #endif template<typename T> rv<T> move(rv<T> t) { return t; } #define BOOST_ENABLE_MOVE_EMULATION(TYPE)\ operator boost::rv<TYPE>() \ { return boost::rv<TYPE>(*this); }\ // #define BOOST_SWAP_BASED_MOVE_ASSIGN(TYPE)\ TYPE& operator=(boost::rv<TYPE> r) \ { \ TYPE tmp(r); \ this->swap(tmp); \ return *this; \ } \ // #else //#ifndef BOOST_HAS_RVALUE_REFS #define BOOST_ENABLE_MOVE_EMULATION(TYPE)\ // #define BOOST_SWAP_BASED_MOVE_ASSIGN(TYPE)\ TYPE& operator=(TYPE &&r) \ { \ TYPE tmp(boost::move(r)); \ this->swap(tmp); \ return *this; \ } \ // template <class T> struct move_identity_type { typedef T type; }; template <class T> inline T&& forward(typename boost::move_identity_type<T>::type&& t) { return t; } template <class T> inline typename boost::remove_reference<T>::type&& move(T&& t) { return t; } template <class T, class U> class move_is_convertible { typedef char true_t; class false_t { char dummy[2]; }; static true_t dispatch(U); static false_t dispatch(...); static T trigger(); public: enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; }; template<class T> class is_movable { public: static const bool value = move_is_convertible<T&&, T>::value; }; #endif //#ifndef BOOST_HAS_RVALUE_REFS #include <boost/config/abi_suffix.hpp> } //namespace boost {

On Jan 4, 2009, at 4:54 PM, Ion Gaztañaga wrote:
I've written (attached) a small, surely not complete, but usable boost/move.hpp header (ok, it could go to boost/detail/move.hpp until a decent review is done) that is tested with a movable class in the file movable_test.cpp, both with Visual 7.1 and move-enabled GCC 4.3.
The goal of this post is to know if that header file would be enough for all current libraries using move emulation. I have more suggestions (new traits like has_trivial_destructor_after_move<>...) but the main question is if that header can be used to agree a common protocol between us. It would be really nice if we could rework our code for Boost 1.39.
If the header contains enough for everyone, I'm ready to write some documentation and tests. I know that this Move library is not what many expect (common macros and utilities to write the same code for rvalue-enabled and older compilers) but I'm afraid entropy has already grown too much ;-) and we can't continue waiting while we add more and more emulation code to Boost.
I think a consolidated move library is a very good idea. Thanks for working on it Ion. Some minor comments: * I think we need a move(t) for "non-movable" t (like int, int*, etc.). Otherwise generic code can't move things. * I've grown to dislike my "friend move" setup and like your namespace scope emulated move better. But that does unfortunately expose rv at el. What about putting rv (and company) in some sort of "don't touch" namespace? Naturally the authors wanting to make their classes moveable will have to touch these types. The hope is that clients of A won't be tempted to touch rv<A>. Another solution might be accomplished with making more of rv private and friending rv<T> to T (I haven't tried this yet). The concern is twofold: 1. What is the interface of the move library to the author of the movable type? 2. What is the interface of the move library to the client of the movable type? My hope is that interface-1 will be as small as possible and that interface-2 will be much smaller than interface-1, and preferably compiler-enforced. * On the one hand I have a strong personal distaste for macros like BOOST_ENABLE_MOVE_EMULATION. On the other hand, I guess the author of the movable type is free to not use them (expand them manually) if desired. So consider this more of stylistic comment than a technical one. :-) Perhaps documentation could mention/demonstrate manual expansion for those of us with severe macro allergies. :-) * I think we need some kind of forward emulation, and I'm afraid that no matter what, it is not going to be very good. :-( It should probably strive to be perfect for BOOST_HAS_RVALUE_REFS, and with no code changes moderately acceptable without BOOST_HAS_RVALUE_REFS. * This library should address both move-only types and movable- copyable types (probably in documentation only). I've been using Dave's enable_if_same design for the latter. I haven't looked at other designs though. -Howard

On Jan 4, 2009, at 6:18 PM, Howard Hinnant wrote:
On Jan 4, 2009, at 4:54 PM, Ion Gaztañaga wrote:
I've written (attached) a small, surely not complete, but usable boost/move.hpp header (ok, it could go to boost/detail/move.hpp until a decent review is done) that is tested with a movable class in the file movable_test.cpp, both with Visual 7.1 and move-enabled GCC 4.3.
The goal of this post is to know if that header file would be enough for all current libraries using move emulation. I have more suggestions (new traits like has_trivial_destructor_after_move<>...) but the main question is if that header can be used to agree a common protocol between us. It would be really nice if we could rework our code for Boost 1.39.
If the header contains enough for everyone, I'm ready to write some documentation and tests. I know that this Move library is not what many expect (common macros and utilities to write the same code for rvalue-enabled and older compilers) but I'm afraid entropy has already grown too much ;-) and we can't continue waiting while we add more and more emulation code to Boost.
I think a consolidated move library is a very good idea. Thanks for working on it Ion. Some minor comments:
* I think we need a move(t) for "non-movable" t (like int, int*, etc.). Otherwise generic code can't move things.
* I've grown to dislike my "friend move" setup and like your namespace scope emulated move better. But that does unfortunately expose rv at el. What about putting rv (and company) in some sort of "don't touch" namespace? Naturally the authors wanting to make their classes moveable will have to touch these types. The hope is that clients of A won't be tempted to touch rv<A>. Another solution might be accomplished with making more of rv private and friending rv<T> to T (I haven't tried this yet). The concern is twofold:
1. What is the interface of the move library to the author of the movable type? 2. What is the interface of the move library to the client of the movable type?
My hope is that interface-1 will be as small as possible and that interface-2 will be much smaller than interface-1, and preferably compiler-enforced.
* On the one hand I have a strong personal distaste for macros like BOOST_ENABLE_MOVE_EMULATION. On the other hand, I guess the author of the movable type is free to not use them (expand them manually) if desired. So consider this more of stylistic comment than a technical one. :-) Perhaps documentation could mention/demonstrate manual expansion for those of us with severe macro allergies. :-)
* I think we need some kind of forward emulation, and I'm afraid that no matter what, it is not going to be very good. :-( It should probably strive to be perfect for BOOST_HAS_RVALUE_REFS, and with no code changes moderately acceptable without BOOST_HAS_RVALUE_REFS.
* This library should address both move-only types and movable- copyable types (probably in documentation only). I've been using Dave's enable_if_same design for the latter. I haven't looked at other designs though.
* Oh, one more thought: Templatized tests (one for move-only and one for movable/copyable) such that clients could instantiate the test with their own move-enabled type to ensure that they've done it right (covered all the bases) would be cool. Double-cool if they could run it without knowing anything about the boost testing harness (or even having to build boost). Though it would need to include both passing and compile-time failing tests (complicating the ability to make it simple and portable). -Howard

on Sun Jan 04 2009, Howard Hinnant <hinnant-AT-twcny.rr.com> wrote:
* Oh, one more thought: Templatized tests (one for move-only and one for movable/copyable) such that clients could instantiate the test with their own move-enabled type to ensure that they've done it right (covered all the bases) would be cool.
Also concept checking classes and archetypes, please! -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Howard Hinnant wrote:
On Jan 4, 2009, at 4:54 PM, Ion Gaztañaga wrote: I think a consolidated move library is a very good idea. Thanks for working on it Ion.
I spoke too fast! a) The header has no move guards b) emulation is not working properly when trying to port some Interprocess classes to the new emulation. Although I add the conversion operator (either manually or by macro) functions returning by value don't work sometimes and the private copy constructor is selected by the compiler (Visual 7.1). I know little about conversion operators but the difference between the old move emulation and the new one is that there is no need for a move_return<> type that holds movable-only types. Should the emulation work in these cases? MovableOnly factory(); int main() { MovableOnly m1(factory()); MovableOnly m2(MovableOnly(arg)); return 0; } Maybe I'm doing something wrong but I just gave up after several tries to fix this ;-)
* I think we need a move(t) for "non-movable" t (like int, int*, etc.). Otherwise generic code can't move things.
Ok.
* I've grown to dislike my "friend move" setup and like your namespace scope emulated move better. But that does unfortunately expose rv at el. What about putting rv (and company) in some sort of "don't touch" namespace? Naturally the authors wanting to make their classes moveable will have to touch these types. The hope is that clients of A won't be tempted to touch rv<A>. Another solution might be accomplished with making more of rv private and friending rv<T> to T (I haven't tried this yet). The concern is twofold:
Seems the way to go. The header was just a fast prototype to see if that header elements were enough for all.
1. What is the interface of the move library to the author of the movable type? 2. What is the interface of the move library to the client of the movable type?
My hope is that interface-1 will be as small as possible and that interface-2 will be much smaller than interface-1, and preferably compiler-enforced.
Ok.
* On the one hand I have a strong personal distaste for macros like BOOST_ENABLE_MOVE_EMULATION. On the other hand, I guess the author of the movable type is free to not use them (expand them manually) if desired. So consider this more of stylistic comment than a technical one. :-) Perhaps documentation could mention/demonstrate manual expansion for those of us with severe macro allergies. :-)
Yes, I added macros at the last minute because I saw I had a lot of similar code around but they are perfectly replaced with manual expansion.
* I think we need some kind of forward emulation, and I'm afraid that no matter what, it is not going to be very good. :-( It should probably strive to be perfect for BOOST_HAS_RVALUE_REFS, and with no code changes moderately acceptable without BOOST_HAS_RVALUE_REFS.
Ok. Regards, Ion

on Mon Jan 05 2009, Ion Gaztañaga <igaztanaga-AT-gmail.com> wrote:
Howard Hinnant wrote:
On Jan 4, 2009, at 4:54 PM, Ion Gaztañaga wrote: I think a consolidated move library is a very good idea. Thanks for working on it Ion.
I spoke too fast! a) The header has no move guards b) emulation is not working properly when trying to port some Interprocess classes to the new emulation.
Although I add the conversion operator (either manually or by macro) functions returning by value don't work sometimes and the private copy constructor is selected by the compiler (Visual 7.1). I know little about conversion operators but the difference between the old move emulation and the new one is that there is no need for a move_return<> type that holds movable-only types. Should the emulation work in these cases?
MovableOnly factory();
int main() { MovableOnly m1(factory()); MovableOnly m2(MovableOnly(arg)); return 0; }
Maybe I'm doing something wrong but I just gave up after several tries to fix this ;-)
Have you got the code and tests in the sandbox? I will be happy to take a crack at it. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
MovableOnly factory();
int main() { MovableOnly m1(factory()); MovableOnly m2(MovableOnly(arg)); return 0; }
Maybe I'm doing something wrong but I just gave up after several tries to fix this ;-)
Have you got the code and tests in the sandbox? I will be happy to take a crack at it.
Agggghhhhhh!!! I've lost several hours until I realized that emulation code (and my own first example) does NOT disable copy constructor taking a const reference!! //Movable only type does this(like unique_ptr) private: unique_ptr(unique_ptr &); unique_ptr &operator=(unique_ptr &); instead of private: unique_ptr(const unique_ptr &); unique_ptr &operator=(const unique_ptr &); Sometimes I feel really stupid ;-) Sorry for the noise, Ion

Ion Gaztañaga wrote:
Hi,
I've written (attached) a small, surely not complete, but usable boost/move.hpp header (ok, it could go to boost/detail/move.hpp until a decent review is done) that is tested with a movable class in the file movable_test.cpp, both with Visual 7.1 and move-enabled GCC 4.3.
One small point. template<class T> class rv { public: T* operator->() {return &r_;} }; Please, make it aware of the types with custom operator&. You can use addressof instead.

Ion Gaztañaga <igaztanaga@gmail.com> writes:
I've written (attached) a small, surely not complete, but usable boost/move.hpp header (ok, it could go to boost/detail/move.hpp until a decent review is done) that is tested with a movable class in the file movable_test.cpp, both with Visual 7.1 and move-enabled GCC 4.3.
This is almost identical to the boost.thread move emulation. In Boost.thread, rv<T> is boost::detail::thread_move_t<T>, but most of the other stuff is equivalent. I like the addition of the explicit is_movable trait. If there is support for this as a basis for combined support, I can easily rework boost.thread to use it. Anthony -- Anthony Williams Author of C++ Concurrency in Action | http://www.manning.com/williams Custom Software Development | http://www.justsoftwaresolutions.co.uk Just Software Solutions Ltd, Registered in England, Company Number 5478976. Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK

Anthony Williams wrote:
Ion Gaztañaga <igaztanaga@gmail.com> writes:
I've written (attached) a small, surely not complete, but usable boost/move.hpp header (ok, it could go to boost/detail/move.hpp until a decent review is done) that is tested with a movable class in the file movable_test.cpp, both with Visual 7.1 and move-enabled GCC 4.3.
This is almost identical to the boost.thread move emulation. In Boost.thread, rv<T> is boost::detail::thread_move_t<T>, but most of the other stuff is equivalent.
I was having some problems with some of Interprocess movable classes and Visual 7.1. I just changed is_movable conversion check from T& -> rv<T> to T -> rv<T> and my problems disappeared. I don't know if that would break some existing code, though: template<class T> class is_movable { public: static const bool value = boost::is_convertible<T, detail::rv<T> >::value; };
If there is support for this as a basis for combined support, I can easily rework boost.thread to use it.
That's the idea. I attach a newer version that uses the modified is_movable trait, pushes rv to namespace detail and uses boost::addressof() to implement operator ->(). Regards, Ion // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2007-8 Anthony Williams // (C) Copyright 2009 Howard Hinnant // (C) Copyright 2009 Ion Gaztanaga #include <boost/config.hpp> #include <boost/type_traits/is_convertible.hpp> #ifndef BOOST_MOVE_HPP #define BOOST_MOVE_HPP #ifndef BOOST_HAS_RVALUE_REFS #ifndef BOOST_NO_SFINAE #include <boost/utility/enable_if.hpp> #endif #include <boost/utility/addressof.hpp> #else //#ifndef BOOST_HAS_RVALUE_REFS #include <boost/type_traits/remove_reference.hpp> #endif namespace boost { #include <boost/config/abi_prefix.hpp> #ifndef BOOST_HAS_RVALUE_REFS namespace detail { template<class T> class rv { private: rv &operator=(const rv&); T& r_; public: explicit rv(T& r) : r_(r) {} T* operator->() {return boost::addressof(r_);} T& operator*() {return r_;} }; } //namespace detail template<class T> class is_movable { public: static const bool value = boost::is_convertible<T, detail::rv<T> >::value; }; #ifndef BOOST_NO_SFINAE template<typename T> typename boost::enable_if<boost::is_movable<T>, T>::type move(T& t) { return T(detail::rv<T>(t)); } #endif template<typename T> detail::rv<T> move(detail::rv<T> t) { return t; } #define BOOST_ENABLE_MOVE_EMULATION(TYPE)\ operator boost::detail::rv<TYPE>() \ { return boost::detail::rv<TYPE>(*this); }\ // #define BOOST_SWAP_BASED_MOVE_ASSIGN(TYPE)\ TYPE& operator=(boost::detail::rv<TYPE> r) \ { \ TYPE tmp(r); \ this->swap(tmp); \ return *this; \ } \ // #else //#ifndef BOOST_HAS_RVALUE_REFS #define BOOST_ENABLE_MOVE_EMULATION(TYPE)\ // #define BOOST_SWAP_BASED_MOVE_ASSIGN(TYPE)\ TYPE& operator=(TYPE &&r) \ { \ TYPE tmp(boost::move(r)); \ this->swap(tmp); \ return *this; \ } \ // template <class T> struct move_identity_type { typedef T type; }; template <class T> inline T&& forward(typename boost::move_identity_type<T>::type&& t) { return t; } template <class T> inline typename boost::remove_reference<T>::type&& move(T&& t) { return t; } template <class T, class U> class move_is_convertible { typedef char true_t; class false_t { char dummy[2]; }; static true_t dispatch(U); static false_t dispatch(...); static T trigger(); public: enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; }; template<class T> class is_movable { public: static const bool value = move_is_convertible<T&&, T>::value; }; #endif //#ifndef BOOST_HAS_RVALUE_REFS #include <boost/config/abi_suffix.hpp> } //namespace boost { #endif //#ifndef BOOST_MOVE_HPP

2009/1/4 Ion Gaztañaga <igaztanaga@gmail.com>:
Howard's unique_ptr contribution has shown again the need for a unified move emulation in Boost. We already have move emulation at least in 5 libraries:
In the move library I was working on, I wasn't aiming for unified move emulation, instead it's meant to be flexible enough to support different move implementations. This would still be important when using libraries outside of boost, as they can't be expected to use our implementation.
-> Unordered: based on Adobe's move library. It's more advanced than the previous one, but Adobe's own library says (http://stlab.adobe.com/group__move__related.html) that a Movable type must satisfy the requirements of concept Regular, which has copy constructor (thus disabling move-only types!). I don't know if the move emulation itself uses Regular requirements.
Move only types are possible (see the attached example, it uses the library at http://svn.boost.org/svn/boost/sandbox/move, although I haven't updated the documentation yet. it's a similar technique to thread's). There is a problem - it doesn't support taking a const reference to a returned noncopyable type. I think your unique_ptr deals with this case correctly, but it is more complicated to implement. If it could be made easy that would be ideal. I'm probably not going to have any time to work on this in the near future, as I've got a few website and documentation tasks to do before the next release. I naively assumed that all I'd need to do was boostify the adobe library, but it ended up being a larger task. So if you want to take it on or do something different feel free. Daniel

Daniel James wrote:
Move only types are possible (see the attached example, it uses the library at http://svn.boost.org/svn/boost/sandbox/move, although I haven't updated the documentation yet.
Ok, they current code in sandbox/move is based on Adobe's move library, but from what you say, Adobe's Regular requirement is not enforced but this emulation, which is good for us.
I'm probably not going to have any time to work on this in the near future, as I've got a few website and documentation tasks to do before the next release. I naively assumed that all I'd need to do was boostify the adobe library, but it ended up being a larger task. So if you want to take it on or do something different feel free.
Ok. If this goes forward, I can try to experiment with unordered and try to test if porting is easy (I suppose there won't be big problems, once we replace boost::unordered_detail::move_from with boost::detail::rv).
Daniel
Thanks, Ion

on Mon Jan 05 2009, "Daniel James" <daniel_james-AT-fmail.co.uk> wrote:
2009/1/4 Ion Gaztañaga <igaztanaga@gmail.com>:
Howard's unique_ptr contribution has shown again the need for a unified move emulation in Boost. We already have move emulation at least in 5 libraries:
In the move library I was working on, I wasn't aiming for unified move emulation, instead it's meant to be flexible enough to support different move implementations. This would still be important when using libraries outside of boost, as they can't be expected to use our implementation.
-> Unordered: based on Adobe's move library. It's more advanced than the previous one, but Adobe's own library says (http://stlab.adobe.com/group__move__related.html) that a Movable type must satisfy the requirements of concept Regular, which has copy constructor (thus disabling move-only types!). I don't know if the move emulation itself uses Regular requirements.
Move only types are possible (see the attached example, it uses the library at http://svn.boost.org/svn/boost/sandbox/move, although I haven't updated the documentation yet. it's a similar technique to thread's). There is a problem - it doesn't support taking a const reference to a returned noncopyable type. I think your unique_ptr deals with this case correctly, but it is more complicated to implement. If it could be made easy that would be ideal.
I'm probably not going to have any time to work on this in the near future, as I've got a few website and documentation tasks to do before the next release. I naively assumed that all I'd need to do was boostify the adobe library, but it ended up being a larger task. So if you want to take it on or do something different feel free.
Aside from contributions I've made to the Adobe move library, I also did a bunch of additional work/thinking about this topic, and some collaboration with Daniel on it. I have some things that are worth including, like: assign(x) = expr that moves from expr if it is a movable rvalue and otherwise swaps if it is a swappable rvalue. Also I figured out how to build "perfect" moving binary operations in C++03 (e.g. string+string), where there are no ambiguities and it will always move if at least one argument is an rvalue. I can send what code I have if you want it. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

on Sun Jan 04 2009, Ion Gaztañaga <igaztanaga-AT-gmail.com> wrote:
Howard's unique_ptr contribution has shown again the need for a unified move emulation in Boost.
Agreed.
We already have move emulation at least in 5 libraries:
-> Interprocess: based on sandbox boost.move library, return types are wrapped in a move_return type.
-> Unordered: based on Adobe's move library. It's more advanced than the previous one, but Adobe's own library says (http://stlab.adobe.com/group__move__related.html) that a Movable type must satisfy the requirements of concept Regular, which has copy constructor (thus disabling move-only types!). I don't know if the move emulation itself uses Regular requirements.
That can easily be overcome. Adobe insists on Regular for reasons of purity, not practicality. The important thing about the Adobe approach is that for movable/copyable types, they don't have adverse effects on their containers, derived classes, or containing classes: they have regular copy ctors and assignment with const rhs. That has huge implications for interoperability with code that isn't specifically move-aware in whatever particular way we choose to express "move-aware" in C++03.
I think code changes in boost::thread and boost::unordered would be minimal if we adopt a solution similar to the one used by Howard's unique_ptr. Interprocess changes are heavier but I'm reading to adapt the library to that solution.
Great.
I've written (attached) a small, surely not complete, but usable boost/move.hpp header (ok, it could go to boost/detail/move.hpp until a decent review is done) that is tested with a movable class in the file movable_test.cpp, both with Visual 7.1 and move-enabled GCC 4.3.
The goal of this post is to know if that header file would be enough for all current libraries using move emulation.
What's really needed before I'd be happy to sign off on it is **a complete suite of correct tests**. That's much more important to me even than having an implementation that passes the tests :-)
I have more suggestions (new traits like has_trivial_destructor_after_move<>...) but the main question is if that header can be used to agree a common protocol between us. It would be really nice if we could rework our code for Boost 1.39.
Agreed.
If the header contains enough for everyone, I'm ready to write some documentation and tests. I know that this Move library is not what many expect (common macros and utilities to write the same code for rvalue-enabled and older compilers)
That can come later. We have to get the C++03 implementation right before it can be macro-ized. Thanks for working on this, -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
That can easily be overcome. Adobe insists on Regular for reasons of purity, not practicality. The important thing about the Adobe approach is that for movable/copyable types, they don't have adverse effects on their containers, derived classes, or containing classes: they have regular copy ctors and assignment with const rhs. That has huge implications for interoperability with code that isn't specifically move-aware in whatever particular way we choose to express "move-aware" in C++03.
Ok. Thanks for the explanation.
What's really needed before I'd be happy to sign off on it is **a complete suite of correct tests**. That's much more important to me even than having an implementation that passes the tests :-)
Ok. I'll write some and a bit of Quickbook documentation.
If the header contains enough for everyone, I'm ready to write some documentation and tests. I know that this Move library is not what many expect (common macros and utilities to write the same code for rvalue-enabled and older compilers)
That can come later. We have to get the C++03 implementation right before it can be macro-ized.
Thanks for working on this,
Thanks for your help. Once we have some basic stuff in the library, it would be great if we could add the "additional work/thinking" you've mentioned. Regards, Ion
participants (6)
-
Andrey Semashev
-
Anthony Williams
-
Daniel James
-
David Abrahams
-
Howard Hinnant
-
Ion Gaztañaga