2 / Copyright (c) 2008-2010 Ion Gaztanaga
4 / Distributed under the Boost Software License, Version 1.0. (See accompanying
5 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 [authors [Gaztanaga, Ion]]
10 [copyright 2008-2014 Ion Gaztanaga]
13 [purpose Move semantics]
15 Distributed under the Boost Software License, Version 1.0.
16 (See accompanying file LICENSE_1_0.txt or copy at
17 [@http://www.boost.org/LICENSE_1_0.txt])
21 [important To be able to use containers of movable-only values you will need to use containers
22 supporting move semantics, like [*Boost.Container] containers]
24 [note Tested compilers: MSVC-7.1, 8.0, 9.0, GCC 4.3-MinGW in C++03 and C++0x modes, Intel 10.1]
26 [section:what_is_boost_move What is Boost.Move?]
28 Rvalue references are a major C++0x feature, enabling move semantics for C++ values. However, we
29 don't need C++0x compilers to take advantage of move semanatics. [*Boost.Move] emulates C++0x
30 move semantics in C++03 compilers and allows writing portable code that works optimally in C++03
35 [section:introduction Introduction]
39 The first 3 chapters are the adapted from the article
40 [@http://www.artima.com/cppsource/rvalue.html ['A Brief Introduction to Rvalue References]]
41 by Howard E. Hinnant, Bjarne Stroustrup, and Bronek Kozicki
45 Copying can be expensive. For example, for vectors `v2=v1` typically involves a function call,
46 a memory allocation, and a loop. This is of course acceptable where we actually need two copies of
47 a vector, but in many cases, we don't: We often copy a `vector` from one place to another, just to
48 proceed to overwrite the old copy. Consider:
52 template <class T> void swap(T& a, T& b)
54 T tmp(a); // now we have two copies of a
55 a = b; // now we have two copies of b
56 b = tmp; // now we have two copies of tmp (aka a)
59 But, we didn't want to have any copies of a or b, we just wanted to swap them. Let's try again:
63 template <class T> void swap(T& a, T& b)
65 T tmp(::boost::move(a));
67 b = ::boost::move(tmp);
70 This `move()` gives its target the value of its argument, but is not obliged to preserve the value
71 of its source. So, for a `vector`, `move()` could reasonably be expected to leave its argument as
72 a zero-capacity vector to avoid having to copy all the elements. In other words, [*move is a potentially
75 In this particular case, we could have optimized swap by a specialization. However, we can't
76 specialize every function that copies a large object just before it deletes or overwrites it. That
77 would be unmanageable.
79 In C++0x, move semantics are implemented with the introduction of rvalue references. They allow us to
80 implement `move()` without verbosity or runtime overhead. [*Boost.Move] is a library that offers tools
81 to implement those move semantics not only in compilers with `rvalue references` but also in compilers
86 [section:implementing_movable_classes Implementing copyable and movable classes]
88 [import ../example/doc_clone_ptr.cpp]
90 [section:copyable_and_movable_cpp0x Copyable and movable classes in C++0x]
92 Consider a simple handle class that owns a resource and also provides copy semantics
93 (copy constructor and assignment). For example a `clone_ptr` might own a pointer, and call
94 `clone()` on it for copying purposes:
106 explicit clone_ptr(T* p = 0) : ptr(p) {}
109 ~clone_ptr() { delete ptr; }
112 clone_ptr(const clone_ptr& p)
113 : ptr(p.ptr ? p.ptr->clone() : 0) {}
115 clone_ptr& operator=(const clone_ptr& p)
119 T *p = p.ptr ? p.ptr->clone() : 0;
127 clone_ptr(clone_ptr&& p)
128 : ptr(p.ptr) { p.ptr = 0; }
130 clone_ptr& operator=(clone_ptr&& p)
134 std::swap(ptr, p.ptr);
141 // Other operations...
144 `clone_ptr` has expected copy constructor and assignment semantics, duplicating resources when copying.
145 Note that copy constructing or assigning a `clone_ptr` is a relatively expensive operation:
149 `clone_ptr` is code that you might find in today's books on C++, except for the part marked as
150 `move semantics`. That part is implemented in terms of C++0x `rvalue references`. You can find
151 some good introduction and tutorials on rvalue references in these papers:
153 * [@http://www.artima.com/cppsource/rvalue.html ['A Brief Introduction to Rvalue References]]
154 * [@http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx ['Rvalue References: C++0x Features in VC10, Part 2]]
156 When the source of the copy is known to be a `rvalue` (e.g.: a temporary object), one can avoid the
157 potentially expensive `clone()` operation by pilfering source's pointer (no one will notice!). The move
158 constructor above does exactly that, leaving the rvalue in a default constructed state. The move assignment
159 operator simply does the same freeing old resources.
161 Now when code tries to copy a rvalue `clone_ptr`, or if that code explicitly gives permission to
162 consider the source of the copy a rvalue (using `boost::move`), the operation will execute much faster.
168 [section:copyable_and_movable_cpp03 Copyable and movable classes in portable syntax for both C++03 and C++0x compilers]
170 Many aspects of move semantics can be emulated for compilers not supporting `rvalue references`
171 and [*Boost.Move] offers tools for that purpose. With [*Boost.Move] we can write `clone_ptr`
172 so that it will work both in compilers with rvalue references and those who conform to C++03.
173 You just need to follow these simple steps:
175 * Put the following macro in the [*private] section:
176 [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE(classname)]
177 * Leave copy constructor as is.
178 * Write a copy assignment taking the parameter as
179 [macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF(classname)]
180 * Write a move constructor and a move assignment taking the parameter as
181 [macroref BOOST_RV_REF BOOST_RV_REF(classname)]
183 Let's see how are applied to `clone_ptr`:
189 [*Question]: What about types that don't own resources? (E.g. `std::complex`?)
191 No work needs to be done in that case. The copy constructor is already optimal.
195 [section:composition_inheritance Composition or inheritance]
197 For classes made up of other classes (via either composition or inheritance), the move constructor
198 and move assignment can be easily coded using the `boost::move` function:
200 [clone_ptr_base_derived]
202 [important Due to limitations in the emulation code, a cast to `Base &` is needed before moving the base part in the move
203 constructor and call Base's move constructor instead of the copy constructor.]
205 Each subobject will now be treated individually, calling move to bind to the subobject's move
206 constructors and move assignment operators. `Member` has move operations coded (just like
207 our earlier `clone_ptr` example) which will completely avoid the tremendously more expensive
210 [clone_ptr_move_derived]
212 Note above that the argument x is treated as a lvalue reference. That's why it is necessary to
213 say `move(x)` instead of just x when passing down to the base class. This is a key safety feature of move
214 semantics designed to prevent accidently moving twice from some named variable. All moves from
215 lvalues occur explicitly.
219 [section:movable_only_classes Movable but Non-Copyable Types]
221 Some types are not amenable to copy semantics but can still be made movable. For example:
223 * `unique_ptr` (non-shared, non-copyable ownership)
224 * A type representing a thread of execution
225 * A type representing a file descriptor
227 By making such types movable (though still non-copyable) their utility is tremendously
228 increased. Movable but non-copyable types can be returned by value from factory functions:
232 file_descriptor create_file(/* ... */);
234 file_descriptor data_file;
236 data_file = create_file(/* ... */); // No copies!
238 In the above example, the underlying file handle is passed from object to object, as long
239 as the source `file_descriptor` is a rvalue. At all times, there is still only one underlying file
240 handle, and only one `file_descriptor` owns it at a time.
242 To write a movable but not copyable type in portable syntax, you need to follow these simple steps:
244 * Put the following macro in the [*private] section:
245 [macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE(classname)]
246 * Write a move constructor and a move assignment taking the parameter as
247 [macroref BOOST_RV_REF BOOST_RV_REF(classname)]
249 Here's the definition of `file descriptor` using portable syntax:
251 [import ../example/doc_file_descriptor.cpp]
252 [file_descriptor_def]
255 /Many standard algorithms benefit from moving elements of the sequence as opposed to
256 /copying them. This not only provides better performance (like the improved `swap`
257 /implementation described above), but also allows these algorithms to operate on movable
258 /but non-copyable types. For example the following code sorts a `vector<unique_ptr<T>>`
259 /based on comparing the pointed-to types:
263 / struct indirect_less
266 / bool operator()(const T& x, const T& y)
270 / std::vector<std::unique_ptr<A>> v;
272 / std::sort(v.begin(), v.end(), indirect_less());
275 /As sort moves the unique_ptr's around, it will use swap (which no longer requires Copyability)
276 /or move construction / move assignment. Thus during the entire algorithm, the invariant that
277 /each item is owned and referenced by one and only one smart pointer is maintained. If the
278 /algorithm were to attempt a copy (say by programming mistake) a compile time error would result.
283 [section:move_and_containers Containers and move semantics]
285 Movable but non-copyable types can be safely inserted into containers and
286 movable and copyable types are more efficiently handled if those containers
287 internally use move semantics instead of copy semantics.
288 If the container needs to "change the location" of an element
289 internally (e.g. vector reallocation) it will move the element instead of copying it.
290 [*Boost.Container] containers are move-aware so you can write the following:
292 [file_descriptor_example]
296 [section:construct_forwarding Constructor Forwarding]
298 Consider writing a generic factory function that returns an object for a newly
299 constructed generic type. Factory functions such as this are valuable for encapsulating
300 and localizing the allocation of resources. Obviously, the factory function must accept
301 exactly the same sets of arguments as the constructors of the type of objects constructed:
305 template<class T> T* factory_new()
308 template<class T> T* factory_new(a1)
309 { return new T(a1); }
311 template<class T> T* factory_new(a1, a2)
312 { return new T(a1, a2); }
314 Unfortunately, in C++03 the much bigger issue with this approach is that the N-argument case
315 would require 2^N overloads, immediately discounting this as a general solution. Fortunately,
316 most constructors take arguments by value, by const-reference or by rvalue reference. If these
317 limitations are accepted, the forwarding emulation of a N-argument case requires just N overloads.
318 This library makes this emulation easy with the help of `BOOST_FWD_REF` and
321 [import ../example/doc_construct_forward.cpp]
322 [construct_forward_example]
324 Constructor forwarding comes in handy to implement placement insertion in containers with
325 just N overloads if the implementor accepts the limitations of this type of forwarding for
326 C++03 compilers. In compilers with rvalue references perfect forwarding is achieved.
330 [section:move_return Implicit Move when returning a local object]
332 The C++ standard specifies situations where an implicit move operation is safe and the
333 compiler can use it in cases were the (Named) Return Value Optimization) can't be used.
334 The typical use case is when a function returns a named (non-temporary) object by value
335 and the following code will perfectly compile in C++11:
339 //Even if movable can't be copied
340 //the compiler will call the move-constructor
341 //to generate the return value
343 //The compiler can also optimize out the move
344 //and directly construct the object 'm'
349 //(1) moved instead of copied
354 movable m(factory());
357 In compilers without rvalue references and some non-conforming compilers (such as Visual C++ 2010/2012)
358 the line marked with `(1)` would trigger a compilation error because `movable` can't be copied. Using a explicit
359 `::boost::move(tmp)` would workaround this limitation but it would code suboptimal in C++11 compilers
360 (as the compile could not use (N)RVO to optimize-away the copy/move).
362 [*Boost.Move] offers an additional macro called [macroref BOOST_MOVE_RET BOOST_MOVE_RET] that can be used to
363 alleviate this problem obtaining portable move-on-return semantics. Let's use the previously presented
364 movable-only `movable` class with classes `copyable` (copy-only type), `copy_movable` (can be copied and moved) and
365 `non_copy_movable` (non-copyable and non-movable):
367 [import ../example/copymovable.hpp]
368 [copy_movable_definition]
370 and build a generic factory function that returns a newly constructed value or a reference to an already
373 [import ../example/doc_move_return.cpp]
374 [move_return_example]
376 [*Caution]: When using this macro in a non-conforming or C++03
377 compilers, a move will be performed even if the C++11 standard does not allow it
378 (e.g. returning a static variable). The user is responsible for using this macro
379 only used to return local objects that met C++11 criteria. E.g.:
385 copy_movable operator()() const
387 //ERROR! The Standard does not allow implicit move returns when the object to be returned
388 //does not met the criteria for elision of a copy operation (such as returning a static member data)
389 //In C++03 compilers this will MOVE resources from cm
390 //In C++11 compilers this will COPY resources from cm
391 //so DON'T use use BOOST_MOVE_RET without care.
392 return BOOST_MOVE_RET(copy_movable, cm);
395 static copy_movable cm;
399 [*Note]: When returning a temporary object `BOOST_MOVE_REF` is not needed as copy ellision rules will work on
400 both C++03 and C++11 compilers.
404 //Note: no BOOST_MOVE_RET
405 movable get_movable()
406 { return movable(); }
408 copy_movable get_copy_movable()
409 { return copy_movable(); }
411 copyable get_copyable()
412 { return copyable(); }
417 [section:move_iterator Move iterators]
421 template<class Iterator>
425 move_iterator<It> make_move_iterator(const It &it);
427 [classref boost::move_iterator move_iterator] is an iterator adaptor with the
428 same behavior as the underlying iterator
429 except that its dereference operator implicitly converts the value returned by the
430 underlying iterator's dereference operator to a rvalue reference: `boost::move(*underlying_iterator)`
431 It is a read-once iterator, but can have up to random access traversal characteristics.
433 `move_iterator` is very useful because some generic algorithms and container insertion functions
434 can be called with move iterators to replace copying with moving. For example:
436 [import ../example/movable.hpp]
439 `movable` objects can be moved from one container to another using move iterators and insertion
440 and assignment operations.w
442 [import ../example/doc_move_iterator.cpp]
443 [move_iterator_example]
447 [section:move_inserters Move inserters]
449 Similar to standard insert iterators, it's possible to deal with move insertion in the same way
450 as writing into an array. A special kind of iterator adaptors, called move insert iterators, are
451 provided with this library. With regular iterator classes,
455 while (first != last) *result++ = *first++;
457 causes a range [first,last) to be copied into a range starting with result. The same code with
458 result being a move insert iterator will move insert corresponding elements into the container.
459 This device allows all of the copying algorithms in the library to work in the move insert mode
460 instead of the regular overwrite mode. This library offers 3 move insert iterators and their
465 // Note: C models Container
466 template <typename C>
467 class back_move_insert_iterator;
469 template <typename C>
470 back_move_insert_iterator<C> back_move_inserter(C& x);
472 template <typename C>
473 class front_move_insert_iterator;
475 template <typename C>
476 front_move_insert_iterator<C> front_move_inserter(C& x);
478 template <typename C>
479 class move_insert_iterator;
481 template <typename C>
482 move_insert_iterator<C> move_inserter(C& x, typename C::iterator it);
485 A move insert iterator is constructed from a container and possibly one of its iterators pointing
486 to where insertion takes place if it is neither at the beginning nor at the end of the container.
487 Insert iterators satisfy the requirements of output iterators. `operator*` returns the move insert
488 iterator itself. The assignment `operator=(T& x)` is defined on insert iterators to allow writing
489 into them, it inserts x right before where the insert iterator is pointing. In other words, an
490 `insert iterator` is like a cursor pointing into the container where the insertion takes place.
491 `back_move_iterator` move inserts elements at the end of a container, `front_insert_iterator`
492 move inserts elements at the beginning of a container, and `move_insert_iterator` move inserts
493 elements where the iterator points to in a container. `back_move_inserter`, `front_move_inserter`,
494 and `move_inserter` are three functions making the insert iterators out of a container. Here's
495 an example of how to use them:
497 [import ../example/doc_move_inserter.cpp]
498 [move_inserter_example]
502 [section:move_algorithms Move algorithms]
504 The standard library offers several copy-based algorithms. Some of them, like `std::copy` or
505 `std::uninitialized_copy` are basic building blocks for containers and other data structures.
506 This library offers move-based functions for those purposes:
510 template<typename I, typename O> O move(I, I, O);
511 template<typename I, typename O> O move_backward(I, I, O);
512 template<typename I, typename F> F uninitialized_move(I, I, F);
513 template<typename I, typename F> F uninitialized_copy_or_move(I, I, F);
516 The first 3 are move variations of their equivalent copy algorithms, but copy assignment and
517 copy construction are replaced with move assignment and construction. The last one has the
518 same behaviour as `std::uninitialized_copy` but since several standand library implementations
519 don't play very well with `move_iterator`s, this version is a portable version for those
520 willing to use move iterators.
522 [import ../example/doc_move_algorithms.cpp]
523 [move_algorithms_example]
527 [section:emulation_limitations Emulation limitations]
529 Like any emulation effort, the library has some limitations users should take in
530 care to achieve portable and efficient code when using the library with C++03 conformant compilers:
532 [section:emulation_limitations_base Initializing base classes]
534 When initializing base classes in move constructors, users must
535 cast the reference to a base class reference before moving it. Example:
539 //Portable and efficient
540 Derived(BOOST_RV_REF(Derived) x) // Move ctor
541 : Base(boost::move(static_cast<Base&>(x))),
542 mem_(boost::move(x.mem_)) { }
545 If casting is not performed the emulation will not move construct
546 the base class, because no conversion is available from `BOOST_RV_REF(Derived)`
547 to `BOOST_RV_REF(Base)`. Without the cast we might obtain a compilation
548 error (for non-copyable types) or a less-efficient move constructor (for copyable types):
552 //If Derived is copyable, then Base is copy-constructed.
553 //If not, a compilation error is issued
554 Derived(BOOST_RV_REF(Derived) x) // Move ctor
555 : Base(boost::move(x)),
556 mem_(boost::move(x.mem_)) { }
560 [section:template_parameters Template parameters for perfect forwarding]
562 The emulation can't deal with C++0x reference collapsing rules that allow perfect forwarding:
568 void forward_function(T &&t)
569 { inner_function(std::forward<T>(t); }
571 //Wrong C++03 emulation
573 void forward_function(BOOST_RV_REF<T> t)
574 { inner_function(boost::forward<T>(t); }
576 In C++03 emulation BOOST_RV_REF doesn't catch any const rlvalues. For more details on
577 forwarding see [link move.construct_forwarding Constructor Forwarding] chapter.
581 [section:emulation_limitations_binding Binding of rvalue references to lvalues]
584 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html first rvalue reference]
585 proposal allowed the binding of rvalue references to lvalues:
596 Later, as explained in
597 [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2812.html ['Fixing a Safety Problem with Rvalue References]]
598 this behaviour was considered dangerous and eliminated this binding so that rvalue references adhere to the
599 principle of type-safe overloading: ['Every function must be type-safe in isolation, without regard to how it has been overloaded]
601 [*Boost.Move] can't emulate this type-safe overloading principle for C++03 compilers:
605 //Allowed by move emulation
607 BOOST_RV_REF(movable) r = m;
611 [section:assignment_operator Assignment operator in classes derived from or holding copyable and movable types]
613 The macro [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE] needs to
614 define a copy constructor for `copyable_and_movable` taking a non-const parameter in C++03 compilers:
618 //Generated by BOOST_COPYABLE_AND_MOVABLE
619 copyable_and_movable &operator=(copyable_and_movable&){/**/}
621 Since the non-const overload of the copy constructor is generated, compiler-generated
622 assignment operators for classes containing `copyable_and_movable`
623 will get the non-const copy constructor overload, which will surely surprise users:
629 copyable_and_movable c;
632 void func(const holder& h)
634 holder copy_h(h); //<--- ERROR: can't convert 'const holder&' to 'holder&'
635 //Compiler-generated copy constructor is non-const:
636 // holder& operator(holder &)
640 This limitation forces the user to define a const version of the copy assignment,
641 in all classes holding copyable and movable classes which might be annoying in some cases.
643 An alternative is to implement a single `operator =()` for copyable and movable classes
644 [@http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ using "pass by value" semantics]:
648 T& operator=(T x) // x is a copy of the source; hard work already done
650 swap(*this, x); // trade our resources for x's
651 return *this; // our (old) resources get destroyed with x
654 However, "pass by value" is not optimal for classes (like containers, strings, etc.) that reuse resources
655 (like previously allocated memory) when x is assigned from a lvalue.
661 [section:how_the_library_works How the library works]
663 [*Boost.Move] is based on macros that are expanded to true rvalue references in C++0x compilers
664 and emulated rvalue reference classes and conversion operators in C++03 compilers.
666 In C++03 compilers [*Boost.Move] defines a class named `::boost::rv`:
676 void operator=(rv const&);
679 which is convertible to the movable base class (usual C++ derived to base conversion). When users mark
680 their classes as [macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE] or
681 [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE], these macros define conversion
682 operators to references to `::boost::rv`:
686 #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
688 operator ::boost::rv<TYPE>&() \
689 { return *static_cast< ::boost::rv<TYPE>* >(this); }\
690 operator const ::boost::rv<TYPE>&() const \
691 { return static_cast<const ::boost::rv<TYPE>* >(this); }\
695 [macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE] also declares a
696 private copy constructor and assignment. [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE]
697 defines a non-const copy constructor `TYPE &operator=(TYPE&)` that forwards to a const version:
699 #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
701 TYPE& operator=(TYPE &t)\
702 { this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
705 In C++0x compilers `BOOST_COPYABLE_AND_MOVABLE` expands to nothing and `BOOST_MOVABLE_BUT_NOT_COPYABLE`
706 declares copy constructor and assigment operator private.
708 When users define the [macroref BOOST_RV_REF BOOST_RV_REF] overload of a copy constructor/assignment, in
709 C++0x compilers it is expanded to a rvalue reference (`T&&`) overload and in C++03 compilers it is expanded
710 to a `::boost::rv<T> &` overload:
714 #define BOOST_RV_REF(TYPE) ::boost::rv< TYPE >& \
716 When users define the [macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF] overload,
717 it is expanded to a usual copy assignment (`const T &`) overload in C++0x compilers and
718 to a `const ::boost::rv &` overload in C++03 compilers:
722 #define BOOST_COPY_ASSIGN_REF(TYPE) const ::boost::rv< TYPE >&
724 As seen, in [*Boost.Move] generates efficient and clean code for C++0x move
725 semantics, without modifying any resolution overload. For C++03 compilers
726 when overload resolution is performed these are the bindings:
728 * a) non-const rvalues (e.g.: temporaries), bind to `::boost::rv< TYPE >&`
729 * b) const rvalue and lvalues, bind to `const ::boost::rv< TYPE >&`
730 * c) non-const lvalues (e.g. non-const references) bind to `TYPE&`
732 The library does not define the equivalent of
733 [macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF] for copy construction (say, `BOOST_COPY_CTOR_REF`)
734 because nearly all modern compilers implement RVO and this is much more efficient than any move emulation.
735 [funcref boost::move move] just casts `TYPE &` into `::boost::rv<TYPE> &`.
737 Here's an example that demostrates how different rlvalue objects bind to `::boost::rv` references in the
738 presence of three overloads and the conversion operators in C++03 compilers:
740 [import ../example/doc_how_works.cpp]
746 [section:thanks_to Thanks and credits]
748 Thanks to all that developed ideas for move emulation: the first emulation was based on Howard Hinnant
749 emulation code for `unique_ptr`, David Abrahams suggested the use of `class rv`,
750 and Klaus Triendl discovered how to bind const rlvalues using `class rv`.
752 Many thanks to all boosters that have tested, reviewed and improved the library.
756 [section:release_notes Release Notes]
758 [section:release_notes_boost_1_57_00 Boost 1.57 Release]
760 * Added `unique_ptr` smart pointer. Thanks to Howard Hinnant for his excellent unique_ptr emulation code and testsuite.
761 * Added `move_if_noexcept` utility. Thanks to Antony Polukhin for the implementation.
763 * [@https://svn.boost.org/trac/boost/ticket/9785 Trac #9785: ['"Compiler warning with intel icc in boost/move/core.hpp"]],
764 * [@https://svn.boost.org/trac/boost/ticket/10460 Trac #10460: ['"Compiler error due to looser throw specifier"]],
765 * [@https://github.com/boostorg/move/pull/3 Git Pull #3: ['"Don't delete copy constructor when rvalue references are disabled"]],
769 [section:release_notes_boost_1_56_00 Boost 1.56 Release]
771 * Added [macroref BOOST_MOVE_RET BOOST_MOVE_RET].
773 * [@https://svn.boost.org/trac/boost/ticket/9482 #9482: ['"MSVC macros not undefined in boost/move/detail/config_end.hpp"]],
774 * [@https://svn.boost.org/trac/boost/ticket/9045 #9045: ['"Wrong macro name on docs"]],
775 * [@https://svn.boost.org/trac/boost/ticket/8420 #8420: ['"move's is_convertible does not compile with aligned data"]].
779 [section:release_notes_boost_1_55_00 Boost 1.55 Release]
781 * Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7952 #7952],
782 [@https://svn.boost.org/trac/boost/ticket/8764 #8764],
783 [@https://svn.boost.org/trac/boost/ticket/8765 #8765],
784 [@https://svn.boost.org/trac/boost/ticket/8842 #8842],
785 [@https://svn.boost.org/trac/boost/ticket/8979 #8979].
790 [section:release_notes_boost_1_54_00 Boost 1.54 Release]
793 * Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7969 #7969],
794 [@https://svn.boost.org/trac/boost/ticket/8231 #8231],
795 [@https://svn.boost.org/trac/boost/ticket/8765 #8765].
799 [section:release_notes_boost_1_53_00 Boost 1.53 Release]
801 * Better header segregation (bug
802 [@https://svn.boost.org/trac/boost/ticket/6524 #6524]).
803 * Small documentation fixes
804 * Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros.
805 * Fixed [@https://svn.boost.org/trac/boost/ticket/7830 #7830],
806 [@https://svn.boost.org/trac/boost/ticket/7832 #7832].
810 [section:release_notes_boost_1_51_00 Boost 1.51 Release]
813 [@https://svn.boost.org/trac/boost/ticket/7095 #7095],
814 [@https://svn.boost.org/trac/boost/ticket/7031 #7031].
818 [section:release_notes_boost_1_49_00 Boost 1.49 Release]
821 [@https://svn.boost.org/trac/boost/ticket/6417 #6417],
822 [@https://svn.boost.org/trac/boost/ticket/6183 #6183],
823 [@https://svn.boost.org/trac/boost/ticket/6185 #6185],
824 [@https://svn.boost.org/trac/boost/ticket/6395 #6395],
825 [@https://svn.boost.org/trac/boost/ticket/6396 #6396],
831 [xinclude autodoc.xml]