Drake
copyable_unique_ptr< T > Class Template Reference

A smart pointer with deep copy semantics. More...

#include <drake/common/copyable_unique_ptr.h>

Inheritance diagram for copyable_unique_ptr< T >:
[legend]
Collaboration diagram for copyable_unique_ptr< T >:
[legend]

Public Member Functions

Constructors
 copyable_unique_ptr () noexcept
 Default constructor stores a nullptr. More...
 
 copyable_unique_ptr (T *ptr) noexcept
 Given a pointer to a writable heap-allocated object, take over ownership of that object. 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_ptroperator= (T *ptr) 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_ptroperator= (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_ptroperator= (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_ptroperator= (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_ptroperator= (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_ptroperator= (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_ptroperator= (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_ptroperator= (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_ptroperator= (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_ptroperator= (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...
 

Related Functions

(Note that these are not member functions.)

template<class charT , class traits , class T >
std::basic_ostream< charT, traits > & operator<< (std::basic_ostream< charT, traits > &os, const copyable_unique_ptr< T > &cu_ptr)
 Output the system-dependent representation of the pointer contained in a copyable_unique_ptr object. More...
 

Detailed Description

template<typename T>
class drake::copyable_unique_ptr< T >

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 a public copy constructor, or it must be "cloneable" (see is_cloneable for definition). A class can be tested for compatibility using the is_copyable_unique_ptr_compatible struct.

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:

  1. It always uses a default deleter.
  2. There is no array version.
  3. To allow for future copy-on-write optimizations, there is a distinction between writable and const access, the get() method is modified to return only a const pointer, with get_mutable() added to return a writable pointer.

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.:

copyable_unique_ptr<Foo> ptr = make_unique<Foo>(...);

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:

copyable_unique_ptr<Base> cu_ptr = make_unique<Derived>();
copyable_unique_ptr<Base> other_cu_ptr = cu_ptr; // Triggers a copy.
is_dynamic_castable<Derived>(cu_other_ptr.get()); // Should be true.

This works for well-designed polymorphic classes.

Warning
Ill-formed polymorphic classes can lead to fatal type slicing of the referenced object, such that the new copy contains an instance of Base instead of Derived. Some mistakes that would lead to this degenerate behavior:
  • The Base class has a public copy constructor.
  • The Base class's Clone() implementation does not invoke the Derived class's implementation of a suitable virtual method.

Constructor & Destructor Documentation

copyable_unique_ptr ( )
inlinenoexcept

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.

copyable_unique_ptr ( T *  ptr)
inlineexplicitnoexcept

Given a pointer to a writable heap-allocated object, take over ownership of that object.

No copying occurs.

copyable_unique_ptr ( const copyable_unique_ptr< T > &  cu_ptr)
inline

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.

copyable_unique_ptr ( const std::unique_ptr< U > &  u_ptr)
inlineexplicit

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.

copyable_unique_ptr ( copyable_unique_ptr< T > &&  cu_ptr)
inlinenoexcept

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.

copyable_unique_ptr ( std::unique_ptr< T > &&  u_ptr)
inlineexplicitnoexcept

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.

copyable_unique_ptr ( std::unique_ptr< U > &&  u_ptr)
inlineexplicitnoexcept

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.

Member Function Documentation

bool empty ( ) const
inlinenoexcept

Return true if this container is empty, which is the state the container is in immediately after default construction and various other operations.

const T* get ( ) const
inlinenoexcept

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.

Here is the caller graph for this function:

T* get_mutable ( )
inlinenoexcept

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.

Warning
If copyable_unique_ptr is instantiated on a const template parameter (e.g., copyable_unique_ptr<const Foo>), then get_mutable() returns a const pointer.
copyable_unique_ptr& operator= ( T *  ptr)
inlinenoexcept

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)
inline

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)
inline

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)
inline

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)
inline

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)
inline

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.

copyable_unique_ptr& operator= ( copyable_unique_ptr< T > &&  cu_ptr)
inlinenoexcept

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.

copyable_unique_ptr& operator= ( copyable_unique_ptr< U > &&  cu_ptr)
inlinenoexcept

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.

copyable_unique_ptr& operator= ( std::unique_ptr< T > &&  u_ptr)
inlinenoexcept

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.

copyable_unique_ptr& operator= ( std::unique_ptr< U > &&  u_ptr)
inlinenoexcept

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.

Friends And Related Function Documentation

std::basic_ostream< charT, traits > & operator<< ( std::basic_ostream< charT, traits > &  os,
const copyable_unique_ptr< T > &  cu_ptr 
)
related

Output the system-dependent representation of the pointer contained in a copyable_unique_ptr object.

This is equivalent to os << p.get();.

Here is the call graph for this function:


The documentation for this class was generated from the following file: