
On 12/05/2010 22:08, Jeffrey Lee Hellrung, Jr. wrote:
I don't think, as implemented, is_movable works for non-class types (at least that used to be the case, and I think the only change in the implementation has been the introduction of a boost::mpl::bool_). I think for non-class types T, at least in c++03, is_movable<T> should evaluate to false without causing a compiler error.
Well, it shouldn't cause any error, is_convertible should lead to false: //This works in MSVC 7.1 bool mv = ::boost::is_movable<int>::value;
I don't recall seeing anything concerning has_nothrow_move other than a short description about how it defaults to false and could hurt performance if not specialized. Can you explain the intended use for has_nothrow_move? Is this related to N2983 [1]? Speaking of which, do you have any idea what the status of throwing move constructors is as far as the c++ committee is concerned, whether you agree with the resolution provided by N2983, and if so, have you thought about providing move_if_noexcept (or something similar)?
Since this has been a moving target until now, I haven't seriously thought about emulating those proposals, but I do expect to work on them in the future, when they are completely definitive. Regarding performance gains with has_nothrow_move, you can optimize away some exception rollback actions in container internals if you know that moving objets will not throw. And to use some advanced memory allocation strategies, like forward buffer expansion, you need this nothrow guarantees because some containers, like vector, require strong exception guarantees for some operations (like push_back).
If has_nothrow_move turns out to be widely used, it may be a good idea to package the "no-throw-ness" of the move constructor within a move emulation enabling macro (ENABLE_NOTHROW_MOVABLE), e.g., by defining a typedef that has_nothrow_move can detect, or maybe a boolean static constant within the class indicating whether the move constructor throws, so that you can make the "no-throw" property conditional on the "no-throw-ness" of member objects. In any case, one step at a time...
The good part of template specializations is that you don't need to instantiate the class to check if the class has that property, and this is important specially when defining recursive data types like recursive containers: class recursive { vector<recursive> leafs; };
As far as the utility of is_movable in c++0x, it looks like it's only used in uninitialized_move and uninitialized_copy_or_move. This doesn't seem like enough justification to provide it for c++0x, since uninitialized_{copy_or_}move *could* be implemented without it just fine. Furthermore, is_movable will only be true in c++0x if a movable type has a nested typedef boost_move_emulation_t, which seems to exclude, e.g., STL data structures. I would think a simpler course of action would be to relegate is_movable to strictly c++03...
Yes, that might be an option. I do use it in containers for some sfinae tricks, but I think it's only for C++03 code. It seems that in C++0x it's not easy to know if a class really has a rvalue reference overload constructor (or at least, it wasn't some time ago, maybe things have changed in recent proposals-drafts), so it might be possible to limit it to C++03.
I've looked through the documentation and have typo suggestions, but I'll have to get to those later...
Ok, thanks again, Ion