A smart pointer with deep copy semantics.
This is similar to std::unique_ptr
in that it does not permit shared ownership of the contained object. However, unlike std::unique_ptr
, copyable_unique_ptr supports copy and assignment operations, by insisting that the contained object be "copyable". To be copyable, the class must have either an accessible copy constructor, or it must have an accessible clone method with signature
where Foo is the type of the managed object. By "accessible" we mean either that the copy constructor or clone method is public, or friend copyable_unique_ptr<Foo>;
appears in Foo's class declaration.
Generally, the API is modeled as closely as possible on the C++ standard std::unique_ptr
API and copyable_unique_ptr<T> is interoperable with unique_ptr<T>
wherever that makes sense. However, there are some differences:
This class is entirely inline and has no computational or space overhead except when copying is required; it contains just a single pointer and does no reference counting.
Usage
In the simplest use case, the instantiation type will match the type of object it references, e.g.:
In this case, as long Foo
is deemed compatible, the behavior will be as expected, i.e., when ptr
copies, it will contain a reference to a new instance of Foo
.
copyable_unique_ptr can also be used with polymorphic classes – a copyable_unique_ptr, instantiated on a base class, references an instance of a derived class. When copying the object, we would want the copy to likewise contain an instance of the derived class. For example:
This works for well-designed polymorphic classes.
Base
instead of Derived
. Some mistakes that would lead to this degenerate behavior:Base
class's Clone() implementation does not invoke the Derived
class's implementation of a suitable virtual method.T | The type of the contained object, which must be copyable as defined above. May be an abstract or concrete type. |
#include <drake/common/copyable_unique_ptr.h>
Public Member Functions | |
Constructors | |
copyable_unique_ptr () noexcept | |
Default constructor stores a nullptr . More... | |
copyable_unique_ptr (T *raw) noexcept | |
Given a raw pointer to a writable heap-allocated object, take over ownership of that object. More... | |
copyable_unique_ptr (const T &value) | |
Constructs a unique instance of T as a copy of the provided model value. More... | |
copyable_unique_ptr (const copyable_unique_ptr &cu_ptr) | |
Copy constructor is deep; the new copyable_unique_ptr object contains a new copy of the object in the source, created via the source object's copy constructor or Clone() method. More... | |
template<typename U > | |
copyable_unique_ptr (const std::unique_ptr< U > &u_ptr) | |
Copy constructor from a standard unique_ptr of compatible type. More... | |
copyable_unique_ptr (copyable_unique_ptr &&cu_ptr) noexcept | |
Move constructor is very fast and leaves the source empty. More... | |
copyable_unique_ptr (std::unique_ptr< T > &&u_ptr) noexcept | |
Move constructor from a standard unique_ptr . More... | |
template<typename U > | |
copyable_unique_ptr (std::unique_ptr< U > &&u_ptr) noexcept | |
Move construction from a compatible standard unique_ptr . More... | |
Assignment | |
copyable_unique_ptr & | operator= (T *raw) noexcept |
This form of assignment replaces the currently-held object by the given source object and takes over ownership of the source object. More... | |
copyable_unique_ptr & | operator= (const T &ref) |
This form of assignment replaces the currently-held object by a heap-allocated copy of the source object, created using its copy constructor or Clone() method. More... | |
copyable_unique_ptr & | operator= (const copyable_unique_ptr &cu_ptr) |
Copy assignment from copyable_unique_ptr replaces the currently-held object by a copy of the object held in the source container, created using the source object's copy constructor or Clone() method. More... | |
template<typename U > | |
copyable_unique_ptr & | operator= (const copyable_unique_ptr< U > &cu_ptr) |
Copy assignment from a compatible copyable_unique_ptr replaces the currently-held object by a copy of the object held in the source container, created using the source object's copy constructor or Clone() method. More... | |
copyable_unique_ptr & | operator= (const std::unique_ptr< T > &src) |
Copy assignment from a standard unique_ptr replaces the currently-held object by a copy of the object held in the source container, created using the source object's copy constructor or Clone() method. More... | |
template<typename U > | |
copyable_unique_ptr & | operator= (const std::unique_ptr< U > &u_ptr) |
Copy assignment from a compatible standard unique_ptr replaces the currently-held object by a copy of the object held in the source container, created using the source object's copy constructor or Clone() method. More... | |
copyable_unique_ptr & | operator= (copyable_unique_ptr &&cu_ptr) noexcept |
Move assignment replaces the currently-held object by the source object, leaving the source empty. More... | |
template<typename U > | |
copyable_unique_ptr & | operator= (copyable_unique_ptr< U > &&cu_ptr) noexcept |
Move assignment replaces the currently-held object by the compatible source object, leaving the source empty. More... | |
copyable_unique_ptr & | operator= (std::unique_ptr< T > &&u_ptr) noexcept |
Move assignment replaces the currently-held object by the source object, leaving the source empty. More... | |
template<typename U > | |
copyable_unique_ptr & | operator= (std::unique_ptr< U > &&u_ptr) noexcept |
Move assignment replaces the currently-held object by the compatible source object, leaving the source empty. More... | |
Observers | |
bool | empty () const noexcept |
Return true if this container is empty, which is the state the container is in immediately after default construction and various other operations. More... | |
const T * | get () const noexcept |
Return a const pointer to the contained object if any, or nullptr . More... | |
T * | get_mutable () noexcept |
Return a writable pointer to the contained object if any, or nullptr . More... | |
const T & | operator * () const |
Return a const reference to the contained object. More... | |
T & | operator * () |
Return a writable reference to the contained object (if T is itself not const). More... | |
|
noexcept |
Default constructor stores a nullptr
.
No heap allocation is performed. The empty() method will return true when called on a default-constructed copyable_unique_ptr.
|
explicitnoexcept |
Given a raw pointer to a writable heap-allocated object, take over ownership of that object.
No copying occurs.
|
explicit |
Constructs a unique instance of T as a copy of the provided model value.
copyable_unique_ptr | ( | const copyable_unique_ptr< T > & | cu_ptr | ) |
Copy constructor is deep; the new copyable_unique_ptr object contains a new copy of the object in the source, created via the source object's copy constructor or Clone()
method.
If the source container is empty this one will be empty also.
|
explicit |
Copy constructor from a standard unique_ptr
of compatible type.
The copy is deep; the new copyable_unique_ptr object contains a new copy of the object in the source, created via the source object's copy constructor or Clone()
method. If the source container is empty this one will be empty also.
|
noexcept |
Move constructor is very fast and leaves the source empty.
Ownership is transferred from the source to the new copyable_unique_ptr. If the source was empty this one will be empty also. No heap activity occurs.
|
explicitnoexcept |
Move constructor from a standard unique_ptr
.
The move is very fast and leaves the source empty. Ownership is transferred from the source to the new copyable_unique_ptr. If the source was empty this one will be empty also. No heap activity occurs.
|
explicitnoexcept |
Move construction from a compatible standard unique_ptr
.
Type U*
must be implicitly convertible to type T*
. Ownership is transferred from the source to the new copyable_unique_ptr. If the source was empty this one will be empty also. No heap activity occurs.
|
noexcept |
Return true if this container is empty, which is the state the container is in immediately after default construction and various other operations.
|
noexcept |
Return a const pointer to the contained object if any, or nullptr
.
Note that this is different than get()
for the standard smart pointers like std::unique_ptr
which return a writable pointer. Use get_mutable() here for that purpose.
|
noexcept |
Return a writable pointer to the contained object if any, or nullptr
.
Note that you need write access to this container in order to get write access to the object it contains.
copyable_unique_ptr<const Foo>
), then get_mutable() returns a const pointer. const T& operator * | ( | ) | const |
Return a const reference to the contained object.
Note that this is different from std::unique_ptr::operator*()
which would return a non-const reference (if T
is non-const), even if the container itself is const. For a const copyable_unique_ptr will always return a const reference to its contained value.
this != nullptr
reports true
. T& operator * | ( | ) |
Return a writable reference to the contained object (if T is itself not const).
Note that you need write access to this container in order to get write access to the object it contains.
We strongly recommend, that, if dereferencing a copyable_unique_ptr without the intention of mutating the underlying value, prefer to dereference a const copyable_unique_ptr (or use *my_ptr.get()) and not a mutable copyable_unique_ptr. As "copy-on-write" behavior is introduced in the future, this recommended practice will prevent unwanted copies of the underlying value.
If copyable_unique_ptr is instantiated on a const template parameter (e.g., copyable_unique_ptr<const Foo>
), then operator*() must return a const reference.
this != nullptr
reports true
.
|
noexcept |
This form of assignment replaces the currently-held object by the given source object and takes over ownership of the source object.
The currently-held object (if any) is deleted.
copyable_unique_ptr& operator= | ( | const T & | ref | ) |
This form of assignment replaces the currently-held object by a heap-allocated copy of the source object, created using its copy constructor or Clone()
method.
The currently-held object (if any) is deleted.
copyable_unique_ptr& operator= | ( | const copyable_unique_ptr< T > & | cu_ptr | ) |
Copy assignment from copyable_unique_ptr replaces the currently-held object by a copy of the object held in the source container, created using the source object's copy constructor or Clone()
method.
The currently-held object (if any) is deleted. If the source container is empty this one will be empty also after the assignment. Nothing happens if the source and destination are the same container.
copyable_unique_ptr& operator= | ( | const copyable_unique_ptr< U > & | cu_ptr | ) |
Copy assignment from a compatible copyable_unique_ptr replaces the currently-held object by a copy of the object held in the source container, created using the source object's copy constructor or Clone()
method.
The currently-held object (if any) is deleted. If the source container is empty this one will be empty also after the assignment. Nothing happens if the source and destination are the same container.
copyable_unique_ptr& operator= | ( | const std::unique_ptr< T > & | src | ) |
Copy assignment from a standard unique_ptr
replaces the currently-held object by a copy of the object held in the source container, created using the source object's copy constructor or Clone()
method.
The currently-held object (if any) is deleted. If the source container is empty this one will be empty also after the assignment. Nothing happens if the source and destination are the same container.
copyable_unique_ptr& operator= | ( | const std::unique_ptr< U > & | u_ptr | ) |
Copy assignment from a compatible standard unique_ptr
replaces the currently-held object by a copy of the object held in the source container, created using the source object's copy constructor or Clone()
method.
The currently-held object (if any) is deleted. If the source container is empty this one will be empty also after the assignment. Nothing happens if the source and destination are the same container.
|
noexcept |
Move assignment replaces the currently-held object by the source object, leaving the source empty.
The currently-held object (if any) is deleted. The instance is not copied. Nothing happens if the source and destination are the same containers.
|
noexcept |
Move assignment replaces the currently-held object by the compatible source object, leaving the source empty.
The currently-held object (if any) is deleted. The instance is not copied. Nothing happens if the source and destination are the same containers.
|
noexcept |
Move assignment replaces the currently-held object by the source object, leaving the source empty.
The currently-held object (if any) is deleted. The instance is not copied. Nothing happens if the source and destination are the same containers.
|
noexcept |
Move assignment replaces the currently-held object by the compatible source object, leaving the source empty.
The currently-held object (if any) is deleted. The instance is not copied. Nothing happens if the source and destination are the same containers.