
On Mar 13, 2006, at 8:42 AM, Vaclav Vesely wrote:
Hi,
draft of the is_movable trait is attached.
Notes:
- Implicit implementation is based on the has_trivial_copy trait.
- For STL configurations, which defines BOOST_HAS_MOVABLE_STL, is_movable.hpp declares STL containers (and their const versions) as movable. Partial template specialization is required (!defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)).
Open issues:
- I'm not sure with volatiles. has_trivial_copy declares volatile types explicitly as not has_trivial_copy. I don't know why but is_movable should probably follow this.
- I have tested MSVC (6, 7.1 and 8) and GCC (3.2.3 - MinGW) compilers. MSVC is fine but GCC complains with specializations for STL types. It seems to be related to a different macro expansion strategy of preprocessor. I'm not able to use BOOST_PP_COMMA macro correctly. I will appreciate any help.
"is_movable" is an overly vague name for what you're attempting to detect. Given a type T, a non-initialized x, and an initialized y, here is the sequence of statements you're optimizing. ::new(&x) T(move(y)); y.~T(); In the current nomenclature (the move proposal before the committee), there are terms such as "move constructor" and "move assignment". In both of these cases the source is left in a constructed state. It would be very easy to confuse the meaning of "is_movable" with these existing definitions. I don't know what a good name would be, but I tend to think that the following would be getting closer: has_trivial_move_constructor_destructor or: has_trivial_destructive_move_constructor BOOST_HAS_MOVABLE_STL seems overly simplistic, and perhaps even dangerous. Overly simplistic in that for some implementations (e.g. gcc 4.x) some of the containers will have a trivial destructive move constructor and some containers won't. Additionally, for containers that store an Allocator, Comparator, or other policy class, their eligibility (if potentially eligible in the first place), should depend upon the eligibility of the Allocator and/or Comparator (and because of this std::comparators need to be treated - std::less, etc.). And in at least one implementation I'm aware of, eligibility for even something as simple as vector<char> depends on whether you're using the debugging version of the STL. In the debugging version the vector holds a list of outstanding iterators which in turn point back to the vector, making it ineligible. The last point highlights the danger aspect. As currently set up, you can silently get a false positive for eligibility just by switching into debug mode (on at least one implementation). The other danger is that vendors have been known to change the eligibility of some containers from release to release (examples include gcc node-based containers). Since this trait can't be auto- detected for things as complicated as containers, I recommend the trait only be turned on for specific version numbers of a std::lib, and that a true response not be forward compatible (later versions need to be specifically set to true). If this trait is to exist, you can't go wrong with including pair, and perhaps even tuple. At the very least their implementation is entertaining (at least tuple's). :-) -Howard