
1. In the docs, "comes in handful" => "comes in handy" 2. IMO, it's almost irresponsible to advertise move_iterator without saying that it's really *only* safe to use when you know implementation details of the algorithm or function to which you're passing it. In particular, it must not attempt to copy from any given position in the sequence more than once. 3. Why doesn't test_move_inserter use std::copy? 4. This sentence doesn't make any sense to me; it needs clarification. I would make a suggestion, but, well, I don't understand what you're trying to say The last one has the same behaviour as std::uninitialized_copy but since several standand library implementations don't play very well with move_iterators, this version is a portable version for those willing to use move iterators. 5. The section on constructor forwarding seems to imply that constructors are the only thing that will be forwarded, when of course that's not the case. 6. These sentences don't make sense to me together. They have no obvious connection to one another. To which limitations are you referring? Fortunately, most constructors take arguments by value, by const-reference or by rvalue reference. If these limitations are accepted, the forwarding emulation of a N-argument case requires just N overloads. This library makes this emulation easy with the help of BOOST_FWD_REF and boost::forward As far as I can tell from the implementation, BOOST_FWD_REF just generates a const& in emulation mode, which isn't much of an emulation at all. 7. "David Abrahams suggested the use of class rv class": too much class :-) -- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost

Thanks for the comments. 1. Thanks, I'll fix it. 2. Thanks, I'll add it to the documentation. I agree that Move documentation is far from complete. 3. Just because I usually write my own loops (my C programming backgroud, I guess). I'll change this. 4. Using move iterator with C++03 compilers lead to compile errors. Some MSVC versions use a "_Construct" function that wraps placement new. And that funcion takes the argument as a const reference. // TEMPLATE FUNCTION _Construct template<class _T1, class _T2> inline void _Construct(_T1 *_Ptr, const _T2& _Val) { new (_Ptr) _T1(_Val); } then the copy constructor is called instead of the move constructor, making std::unitialized_copy unusable for move-only types. boost::unitialized_copy just tries to avoid this problem so that we can write portable code for C++03+Boost.Move and C++11 compilers. Any suggestion is welcome. 5. I know, but I couldn't find a generic solution for perfect forwarding and forwarding for constructors were an important use case, specially to implement containers with move semantics for C++03 compilers. Open to suggestions and changes. 6. If you limit yourself to constructors taking const references or rvalue references (that if you avoid non-const reference or const rvalue reference arguments in constructors) then this approach works reasonably well. You only need to write N overloads to implement emplace functions (as we have no variadic templates): emplace(); template<class Arg1> emplace(BOOST_FWD_REF(Arg1) arg1) template<class Arg1, class Arg2> emplace(BOOST_FWD_REF(Arg2) arg2) //... Just as you need to implement emplace for compilers with rvalue references but no variadic templates (like recent MSVC versions) emplace(); template<class Arg1> emplace(Arg1 && arg1) template<class Arg1, class Arg2> emplace(Arg2 &&arg1, Arg2 &&arg2) //... Catching by const T & works because it catches also rv<T> types, that are treated specially by move() and forward() emulation functions to emulate forwarding. 7. ;-) Best, Ion El 27/10/2012 0:53, Dave Abrahams escribió:
1. In the docs, "comes in handful" => "comes in handy"
2. IMO, it's almost irresponsible to advertise move_iterator without saying that it's really *only* safe to use when you know implementation details of the algorithm or function to which you're passing it. In particular, it must not attempt to copy from any given position in the sequence more than once.
3. Why doesn't test_move_inserter use std::copy?
4. This sentence doesn't make any sense to me; it needs clarification. I would make a suggestion, but, well, I don't understand what you're trying to say
The last one has the same behaviour as std::uninitialized_copy but since several standand library implementations don't play very well with move_iterators, this version is a portable version for those willing to use move iterators.
5. The section on constructor forwarding seems to imply that constructors are the only thing that will be forwarded, when of course that's not the case.
6. These sentences don't make sense to me together. They have no obvious connection to one another. To which limitations are you referring?
Fortunately, most constructors take arguments by value, by const-reference or by rvalue reference. If these limitations are accepted, the forwarding emulation of a N-argument case requires just N overloads. This library makes this emulation easy with the help of BOOST_FWD_REF and boost::forward
As far as I can tell from the implementation, BOOST_FWD_REF just generates a const& in emulation mode, which isn't much of an emulation at all.
7. "David Abrahams suggested the use of class rv class": too much class :-)

on Sun Oct 28 2012, Ion Gaztañaga <igaztanaga-AT-gmail.com> wrote:
Thanks for the comments.
1. Thanks, I'll fix it.
Hi Ion, Hate to nag about top-posting, but in this case it truly made everything lots harder to read. Jumping back and forth to correllate numbers is... unfun :-P
1. In the docs, "comes in handful" => "comes in handy"
<snip>
-- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost

El 29/10/2012 13:09, Dave Abrahams escribió:
on Sun Oct 28 2012, Ion Gaztañaga <igaztanaga-AT-gmail.com> wrote:
Thanks for the comments.
1. Thanks, I'll fix it.
Hi Ion,
Hate to nag about top-posting, but in this case it truly made everything lots harder to read. Jumping back and forth to correllate numbers is... unfun :-P
Sorry, you are right.

on Sun Oct 28 2012, Ion Gaztañaga <igaztanaga-AT-gmail.com> wrote:
Best,
Ion
El 27/10/2012 0:53, Dave Abrahams escribió:
4. This sentence doesn't make any sense to me; it needs clarification. I would make a suggestion, but, well, I don't understand what you're trying to say
The last one has the same behaviour as std::uninitialized_copy but since several standand library implementations don't play very well with move_iterators, this version is a portable version for those willing to use move iterators.
4. Using move iterator with C++03 compilers lead to compile errors. Some MSVC versions use a "_Construct" function that wraps placement new. And that funcion takes the argument as a const reference.
// TEMPLATE FUNCTION _Construct template<class _T1, class _T2> inline void _Construct(_T1 *_Ptr, const _T2& _Val) { new (_Ptr) _T1(_Val); }
then the copy constructor is called instead of the move constructor, making std::unitialized_copy unusable for move-only types. boost::unitialized_copy just tries to avoid this problem so that we can write portable code for C++03+Boost.Move and C++11 compilers. Any suggestion is welcome.
That doesn't explain the sentence, I'm afraid. For example, what does move_iterator have to do with any of this? It sounds like you're probably exposing implementation details by mentioning it at all, and if you *did* implement an algorithm by using move_iterator with a standard algorithm, you should change that, because you have no right to expect it to work even in C++11.
5. The section on constructor forwarding seems to imply that constructors are the only thing that will be forwarded, when of course that's not the case.
5. I know, but I couldn't find a generic solution for perfect forwarding and forwarding for constructors were an important use case, specially to implement containers with move semantics for C++03 compilers. Open to suggestions and changes.
I don't see why your solution for constructor forwarding couldn't apply equally well everywhere (since it doesn't really do anything other than pass-by-T const& AFAICT).
6. These sentences don't make sense to me together. They have no obvious connection to one another. To which limitations are you referring?
Fortunately, most constructors take arguments by value, by const-reference or by rvalue reference. If these limitations are accepted, the forwarding emulation of a N-argument case requires just N overloads. This library makes this emulation easy with the help of BOOST_FWD_REF and boost::forward
As far as I can tell from the implementation, BOOST_FWD_REF just generates a const& in emulation mode, which isn't much of an emulation at all.
6. If you limit yourself to constructors taking const references or rvalue references (that if you avoid non-const reference or const rvalue reference arguments in constructors)
This doesn't make any sense to me either. Just in case our wires are crossed on this part: arguments are what you pass to functions. They are lvalues, glvalues, xvalues, rvalues and prvalues. Parameters are what a function receives; they can be references.
then this approach works reasonably well. You only need to write N overloads to implement emplace functions (as we have no variadic templates):
emplace();
template<class Arg1> emplace(BOOST_FWD_REF(Arg1) arg1)
template<class Arg1, class Arg2> emplace(BOOST_FWD_REF(Arg2) arg2)
//...
Just as you need to implement emplace for compilers with rvalue references but no variadic templates (like recent MSVC versions)
emplace();
template<class Arg1> emplace(Arg1 && arg1)
template<class Arg1, class Arg2> emplace(Arg2 &&arg1, Arg2 &&arg2)
//...
Catching by const T & works because it catches also rv<T> types, that are treated specially by move() and forward() emulation functions to emulate forwarding.
I don't see why this wouldn't "work" just as well for non-constructors, provided you're willing to accept the same limitations on their parameter types in C++03. -- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost

El 30/10/2012 0:56, David Abrahams escribió:
That doesn't explain the sentence, I'm afraid. For example, what does move_iterator have to do with any of this? It sounds like you're probably exposing implementation details by mentioning it at all, and if you *did* implement an algorithm by using move_iterator with a standard algorithm, you should change that, because you have no right to expect it to work even in C++11.
Ok. But, isn't move_iterator guaranteed to work for [uninitialized_]copy/copy_n algorithms? For std::copy I read "For each non-negative integer n < (last -first), performs *(result + n) = *(first + n).", and "Complexity: Exactly last - first assignments". Input Iterator requires "*a convertible to T", and move_iterator returns T&&, which is convertible to T. Doesn't this guarantee move_iterator works with std::copy? For uninitialized_copy: Effects: for (; first != last; ++result, ++first) ::new (static_cast<void*>(&*result)) typename iterator_traits<ForwardIterator>::value_type(*first); Doesn't this guarantee move_iterator will always work in C++11 uninitialized_copy? If both algorithms are usable with move_iterators, then I think it's useful to have a boost implementation that work both in C++03 and C++11 compilers. I only added uninitialized_copy, but it could be useful also for uninitialized_copy_n. I'd need to test if std::copy in supported C++03 compilers work with move_iterator. I agree that this is horribly explained in the documentation.
I don't see why your solution for constructor forwarding couldn't apply equally well everywhere (since it doesn't really do anything other than pass-by-T const& AFAICT).
This doesn't make any sense to me either. Just in case our wires are crossed on this part: arguments are what you pass to functions. They are lvalues, glvalues, xvalues, rvalues and prvalues. Parameters are what a function receives; they can be references.
Understood, then can the documentation be improved replacing "most constructors take arguments by value" by "most constructors accept their parameters by value, const reference or rvalue reference"?
Catching by const T & works because it catches also rv<T> types, that are treated specially by move() and forward() emulation functions to emulate forwarding.
I don't see why this wouldn't "work" just as well for non-constructors, provided you're willing to accept the same limitations on their parameter types in C++03.
Of course. If I remember correctly, during the pre-review and review period, I was told that it should be clear that this "portable" forwarding was not a general forwarding solution, but it was targeted to forward arguments to factories, constructors, and emplace functions. The best name I could invent was "constructor forwarding". I'd gladly change the name to something better. As an improvement, it could treat std::/boost::ref as an special case so that we could forward arguments to functions taking parameters by non-const references. Best, Ion

El 30/10/2012 22:34, Ion Gaztañaga escribió:
As an improvement, it could treat std::/boost::ref as an special case so that we could forward arguments to functions taking parameters by non-const references.
Sorry, I just realized that this makes no sense, as we could not forward twice. Ion

5. The section on constructor forwarding seems to imply that constructors are the only thing that will be forwarded, when of course that's not the case.
Shoudn't the forwarding stuff be integrated into the forward adaptor instead? Since, it does emulate fowarding for C++03 compilers. The only thing is, it doesn't use rvalue references when they are available.(which should be fairly trivial to support).
6. These sentences don't make sense to me together. They have no obvious connection to one another. To which limitations are you referring?
Fortunately, most constructors take arguments by value, by const-reference or by rvalue reference. If these limitations are accepted, the forwarding emulation of a N-argument case requires just N overloads. This library makes this emulation easy with the help of BOOST_FWD_REF and boost::forward
As far as I can tell from the implementation, BOOST_FWD_REF just generates a const& in emulation mode, which isn't much of an emulation at all.
Ultimately, it should be a non-const reference when using the forward adaptor in emulation mode.
participants (4)
-
Dave Abrahams
-
David Abrahams
-
Ion Gaztañaga
-
paul Fultz