[move] Reason for BOOST_COPY_ASSIGN_REF?

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I've been studying Boost.Move, with an eye toward using it to incorporate move semantics into the XInt library. Most of it looks pretty straightforward, but I don't understand the reason for the BOOST_COPY_ASSIGN_REF macro. If you already have a copy-constructor that takes a reference, what does it give you? Also, how close is it to being official? I'd like to use it, but if it's not going to be accepted any time soon, I can't justify it. - -- Chad Nelson Oak Circle Software, Inc. * * * -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkvOY7AACgkQp9x9jeZ9/wRK1gCgvukakBrO37sCmHKwdhf9ebsI rt8AmwYk3WwDZkUiUKKXb76Jeuh3n3w4 =8EHR -----END PGP SIGNATURE-----

Chad Nelson wrote:
I've been studying Boost.Move, with an eye toward using it to incorporate move semantics into the XInt library. Most of it looks pretty straightforward, but I don't understand the reason for the BOOST_COPY_ASSIGN_REF macro. If you already have a copy-constructor that takes a reference, what does it give you?
That's why it's called BOOST_COPY_*ASSIGN*_REF. You use it to define the copy assignment operator. It expands to const T& if BOOST_HAS_RVALUE_REFS, and const rv<T>& otherwise. Boost.Move, in the absence of true rvalue references, depends on copy elision to efficiently construct from rvalues (and reasonably so), so there's no need to do anything special with the copy/move constructor combination.
Also, how close is it to being official? I'd like to use it, but if it's not going to be accepted any time soon, I can't justify it.
I can't answer the "how close", but you can still use it in the sense that you can adopt its conventions regarding boost::rv, and (if you choose) ignore the rest of the library. These conventions are: - boost::rv<T>& emulates an rvalue reference (and hence may be safely moved from); and - a move-enabled class T provides a non-const conversion operator to boost::rv<T>& and a const conversion operator to const boost::rv<T>&. - Jeff

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 04/20/2010 11:56 PM, Jeffrey Hellrung wrote:
I've been studying Boost.Move, with an eye toward using it to incorporate move semantics into the XInt library. Most of it looks pretty straightforward, but I don't understand the reason for the BOOST_COPY_ASSIGN_REF macro. If you already have a copy-constructor that takes a reference, what does it give you?
(Sorry, I meant to write operator=, not copy-constructor, there.)
That's why it's called BOOST_COPY_*ASSIGN*_REF. You use it to define the copy assignment operator. It expands to const T& if BOOST_HAS_RVALUE_REFS, and const rv<T>& otherwise. Boost.Move, in the absence of true rvalue references, depends on copy elision to efficiently construct from rvalues (and reasonably so), so there's no need to do anything special with the copy/move constructor combination.
I'm obviously missing some key concept, because very little of that parses. I don't know of any efficient way to determine what that concept might be, so here are some possibly-nonsensical questions to try to scare it into view: - - How is the "copy assignment operator" different from the normal operator=(const T&)? - - *Why* does it expand to const T& if if BOOST_HAS_RVALUE_REFS and const rv<T>& otherwise? rv<T> is an rvalue representation, if I understand correctly, and that isn't equivalent to const T&, is it? - - What undesirable thing(s) would happen if you ignored BOOST_COPY_ASSIGN_REF and simply created a normal operator=(const T&)?
Also, how close is it to being official? I'd like to use it, but if it's not going to be accepted any time soon, I can't justify it.
I can't answer the "how close", but you can still use it in the sense that you can adopt its conventions regarding boost::rv, and (if you choose) ignore the rest of the library. These conventions are: - boost::rv<T>& emulates an rvalue reference (and hence may be safely moved from); and - a move-enabled class T provides a non-const conversion operator to boost::rv<T>& and a const conversion operator to const boost::rv<T>&.
Let me rephrase the question. The current Boost.Move library has been discussed on this list since at least January of 2009, and it's still not approved. So how can I adopt anything regarding boost::rv if the library that defines boost::rv might still not be available if/when my library is ready for inclusion into a Boost release? Would I have to bundle move.hpp with XInt in that case? Or yank out the move stuff completely? - -- Chad Nelson Oak Circle Software, Inc. * * * -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkvOhBwACgkQp9x9jeZ9/wRbqQCg5cIqPohTlv0h0T5VuPR1jxJ+ iQoAn3FhlwZOW411Zci9Y1rlzwfhyId4 =tj0y -----END PGP SIGNATURE-----

Chad Nelson wrote: > On 04/20/2010 11:56 PM, Jeffrey Hellrung wrote: > >>> I've been studying Boost.Move, with an eye toward using it to >>> incorporate move semantics into the XInt library. Most of it looks >>> pretty straightforward, but I don't understand the reason for the >>> BOOST_COPY_ASSIGN_REF macro. If you already have a copy-constructor that >>> takes a reference, what does it give you? > > (Sorry, I meant to write operator=, not copy-constructor, there.) > >> That's why it's called BOOST_COPY_*ASSIGN*_REF. You use it to define >> the copy assignment operator. It expands to const T& if >> BOOST_HAS_RVALUE_REFS, and const rv<T>& otherwise. Boost.Move, in the >> absence of true rvalue references, depends on copy elision to >> efficiently construct from rvalues (and reasonably so), so there's no >> need to do anything special with the copy/move constructor combination. > > I'm obviously missing some key concept, because very little of that > parses. I don't know of any efficient way to determine what that concept > might be, so here are some possibly-nonsensical questions to try to > scare it into view: > > - - How is the "copy assignment operator" different from the normal > operator=(const T&)? > > - - *Why* does it expand to const T& if if BOOST_HAS_RVALUE_REFS and const > rv<T>& otherwise? rv<T> is an rvalue representation, if I understand > correctly, and that isn't equivalent to const T&, is it? > > - - What undesirable thing(s) would happen if you ignored > BOOST_COPY_ASSIGN_REF and simply created a normal operator=(const T&)? If you look at the definition of the move-enabling macros, you'll see that a move-enabled class (under C++03) has the following member functions: operator rv<T>&(); // C1 operator const rv<T>&() const; // C2 T::operator=(T&); // A1 T::operator=(const rv<T>&); // A2 T::operator=(rv<T>&); // A3 The purpose of defining the above array of member functions is to enable rvalues to bind to the move assignment operator (A3) rather than the copy assignment operator (A1 and A2). In fact, that's the hardest part about emulating rvalue references in C++03, and you can still get a good deal of mileage without it. To see how it works, consider which operator= overload gets called when you do T x(...); x = f(); If the return type of f() is T&, its result binds to A1 (directly); if it's const T&, to A2 (via C2); and if it's simply T (so that f() is an rvalue), it (magically) binds to A3 (via C1). If you were to define a T::operator(const T&), then rvalues would bind to this overload (which would be less efficient; we want to move from rvalues, not copy from them). The move-enabling macro defines A1 to simply forward to A2; A2 is what the class author implements. The use of the BOOST_COPY_ASSIGN_REF macro makes it clear what the semantics of A2 ought to be. Of course, none of this is necessary in the presence of rvalue references. Hopefully that answers your questions. >>> Also, how close is it to being official? I'd like to use it, but if >>> it's not going to be accepted any time soon, I can't justify it. >> I can't answer the "how close", but you can still use it in the sense >> that you can adopt its conventions regarding boost::rv, and (if you >> choose) ignore the rest of the library. These conventions are: >> - boost::rv<T>& emulates an rvalue reference (and hence may be safely >> moved from); and >> - a move-enabled class T provides a non-const conversion operator to >> boost::rv<T>& and a const conversion operator to const boost::rv<T>&. > > Let me rephrase the question. The current Boost.Move library has been > discussed on this list since at least January of 2009, and it's still > not approved. So how can I adopt anything regarding boost::rv if the > library that defines boost::rv might still not be available if/when my > library is ready for inclusion into a Boost release? Would I have to > bundle move.hpp with XInt in that case? Or yank out the move stuff > completely? I guess you have a couple options. The goal would be to enable a smooth transition to Boost.Move once accepted: - Include the move.hpp from the boost sandbox, but only (directly) using the definition of boost::rv. For the enabling macros, free functions, etc., use your own implementations (possibly just forwarding to the sandbox implementations) so that changes to the Boost.Move library require minimal retooling on your part. This is what I had in mind originally, but it might not such a good idea as it might cause ODR violations with other libraries taking this approach. In any case, it causes issues when trying to distribute your code, unless you're willing to require users to copy the move library from the sandbox into their boost directory (life could be worse). Perhaps better is... - Clone the Boost.Move library in the sandbox into an inner namespace (xint::detail::rv, xint::detail::move, etc.) and use this "private" rvalue reference emulation framework, in such a way that when Boost.Move is accepted into boost, it will be easy to "lift" your private emulation framework into the boost-standardized one. I know people are generally against the proliferation of private rvalue reference emulation frameworks (myself included), but given the lack of any kind of established convention thus far, it seems like a viable option. Whether either of the above or whatever else you come up with is worth the trouble is up to you. - Jeff

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 04/21/2010 02:30 AM, Jeffrey Hellrung wrote:
I'm obviously missing some key concept, because very little of that parses. I don't know of any efficient way to determine what that concept might be, so here are some possibly-nonsensical questions to try to scare it into view: [...]
If you look at the definition of the move-enabling macros, you'll see that a move-enabled class (under C++03) has the following member functions:
Thanks for the explanation. I think I see it now.
Let me rephrase the question. The current Boost.Move library has been discussed on this list since at least January of 2009, and it's still not approved. So how can I adopt anything regarding boost::rv if the library that defines boost::rv might still not be available if/when my library is ready for inclusion into a Boost release? Would I have to bundle move.hpp with XInt in that case? Or yank out the move stuff completely?
I guess you have a couple options. [...]
By the sound of it, it will probably be approved before XInt makes it to review. So it may not be a problem, but again, thanks for the information. - -- Chad Nelson Oak Circle Software, Inc. * * * -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkvPBtoACgkQp9x9jeZ9/wQvcQCfWpldrf7Gc/sWvnhICDmQhWt+ 4D0An2ybPGPHJhor2q84HfbbeO6BuY8R =UtKW -----END PGP SIGNATURE-----

On 21/04/2010 6:50, Chad Nelson wrote:
Also, how close is it to being official? I'd like to use it, but if it's not going to be accepted any time soon, I can't justify it.
It's going to be reviwed very soon. I'm finishing the final review version with updated containers and a macro option to activate two emulation modes (the one with BOOST_COPY_ASSIGN_REF and the more conservative approach one used in Interprocess). I expect to upload the final version this week, the library has a review manager so we can review it in May. Best, Ion

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 04/21/2010 02:49 AM, Ion Gaztañaga wrote:
Also, how close is it to being official? I'd like to use it, but if it's not going to be accepted any time soon, I can't justify it.
It's going to be reviwed very soon. I'm finishing the final review version with updated containers and a macro option to activate two emulation modes (the one with BOOST_COPY_ASSIGN_REF and the more conservative approach one used in Interprocess).
I expect to upload the final version this week, the library has a review manager so we can review it in May.
Thanks, that's great news. It sounds like I can integrate it with no worries, then. - -- Chad Nelson Oak Circle Software, Inc. * * * -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkvPBywACgkQp9x9jeZ9/wSMNgCfVTLw+aPp8YhE5ecxxHoYcz2o vQEAoJpRoOIbcXPABQiVNKk43YxmTiBT =lezR -----END PGP SIGNATURE-----

Chad Nelson wrote:
- - How is the "copy assignment operator" different from the normal operator=(const T&)?
The "normal operator=(const T&)" *is* the copy assignment operator. That's always been the name of that member function. There can be any number of assignment operators, providing interoperability with other types, but there's only one that is expected to assign from another instance of the same class to make *this a copy of the source. With C++0x, there is also a _move assignment operator_, which uses an rvalue reference. Precision in terminology, especially as the variations increase, is helpful. HTH, _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 04/21/2010 07:22 AM, Stewart, Robert wrote:
- - How is the "copy assignment operator" different from the normal operator=(const T&)?
The "normal operator=(const T&)" *is* the copy assignment operator. [...]
Thanks. As I said, some of those questions could be nonsensical. - -- Chad Nelson Oak Circle Software, Inc. * * * -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkvPB70ACgkQp9x9jeZ9/wTqwgCfUW4vp98Xc5qMcLaN6ASjeR8V PEUAn1ot9zXNTpUJGpPQPHwCHSA4dMsK =0lPP -----END PGP SIGNATURE-----
participants (4)
-
Chad Nelson
-
Ion Gaztañaga
-
Jeffrey Hellrung
-
Stewart, Robert