template<class T>
Corrade::Containers::Pointer class

Lightweight unique pointer.

An alternative to std::unique_ptr from C++11, provides an owning move-only wrapper over a pointer of type T, calling delete on it on destruction. The pointer() convenience function also provides an equivalent for C++14 std::make_unique(), but on C++11 as well. Can be also thought of as a heap-allocated counterpart to Optional.

Compared to std::unique_ptr, this class does proper const propagation as would be expected from any other owning container like Array or String — i.e., it's only possible to mutate the owned data if the instance is not const. There's no STL functionality with such behavior except for the proposed std::indirect_value.

Unlike std::unique_ptr, this class does not provide custom deleters, doesn't work with arrays and doesn't have a constexpr API. On the other hand that makes it fairly simple and lightweight. If you need a custom deleter, use either ScopeGuard or the standard std::unique_ptr. For owning array wrappers use Array, which maintains a size information and also supports custom deleters.

Usage with incomplete types

The Pointer class can wrap an incomplete (forward-declared) type, for example to use it for the PIMPL idiom. The type is expected to be defined when the destructor is called or when using reset(), as otherwise calling delete on a pointer to an incomplete type wouldn't call its destructor, leading to resource leaks. In practice it means that a PIMPL class has to define its copy/move constructors, assignments and the destructor in the source file as well instead of relying on them being added implicitly by the compiler. For example, this is how a header with the forward-declared struct State would have to look like, explicitly declaring but not defining a move constructor, destructor and move assignment:

class Pimpl {
    public:
        explicit Pimpl();

        Pimpl(const Pimpl&) = delete;
        Pimpl(Pimpl&&) noexcept;
        ~Pimpl();
        Pimpl& operator=(const Pimpl&) = delete;
        Pimpl& operator=(Pimpl&&) noexcept;

    private:
        struct State;
        Containers::Pointer<State> _state;
};

The defaulted move constructor, destructor, and move assignment would then be in the source file together with the definition of State:

struct Pimpl::State {
    
};

Pimpl::Pimpl(Pimpl&&) noexcept = default;
Pimpl::~Pimpl() = default;
Pimpl& Pimpl::operator=(Pimpl&&) noexcept = default;

STL compatibility

Instances of Pointer are implicitly move-convertible to and from std::unique_ptr if you include Corrade/Containers/PointerStl.h. The conversion is provided in a separate header to avoid unconditional #include <memory>, which significantly affects compile times. Additionally, the pointer(T&&) overload also allows for such a conversion. Example:

#include <Corrade/Containers/PointerStl.h>



std::unique_ptr<int> a{new int{5}};
Containers::Pointer<int> b = std::move(a);

std::unique_ptr<int> c = Containers::pointer<int>(12);

auto d = Containers::pointer(std::unique_ptr<int>{new int{5}});
        // d is Containers::Pointer<int>

Public types

using Type = T new in Git master
Value type.

Constructors, destructors, conversion operators

Pointer(std::nullptr_t = nullptr) noexcept
Default constructor.
Pointer(T* pointer) explicit noexcept
Construct a unique pointer by value.
template<class ... Args>
Pointer(Corrade::InPlaceInitT, Args && ... args) explicit
Construct a unique pointer in-place.
template<class U, class = typename std::enable_if<std::is_base_of<T, U>::value>::type>
Pointer(Pointer<U>&& other) noexcept
Construct a unique pointer from another of a derived type.
template<class U, class = decltype(Implementation::PointerConverter<T, U>::from(std::declval<U && >()))>
Pointer(U&& other) noexcept
Construct a unique pointer from external representation.
Pointer(const Pointer<T>&) deleted
Copying is not allowed.
Pointer(Pointer<T>&& other) noexcept
Move constructor.
template<class U, class = decltype(Implementation::PointerConverter<T, U>::to(std::declval<Pointer<T> && >()))>
operator U() &&
Convert the unique pointer to external representation.
~Pointer()
Destructor.
operator bool() const explicit
Whether the pointer is non-null.

Public functions

auto operator=(const Pointer<T>&) -> Pointer<T>& deleted
Copying is not allowed.
auto operator=(Pointer<T>&& other) -> Pointer<T>& noexcept
Move assignment.
auto operator==(std::nullptr_t) const -> bool
Equality comparison to a null pointer.
auto operator!=(std::nullptr_t) const -> bool
Non-equality comparison to a null pointer.
auto get() -> T*
Underlying pointer value.
auto get() const -> const T*
auto operator->() -> T*
Access the underlying pointer.
auto operator->() const -> const T*
auto operator*() -> T&
Access the underlying pointer.
auto operator*() const -> const T&
void reset(T* pointer = nullptr)
Reset the pointer to a new value.
template<class ... Args>
auto emplace(Args && ... args) -> T&
Emplace a new value.
template<class U, class ... Args>
auto emplace(Args && ... args) -> U& new in Git master
Emplace a new value of a derived type.
auto release() -> T*
Release the pointer ownership.

Function documentation

template<class T>
Corrade::Containers::Pointer<T>::Pointer(std::nullptr_t = nullptr) noexcept

Default constructor.

Creates a nullptr unique pointer.

template<class T>
Corrade::Containers::Pointer<T>::Pointer(T* pointer) explicit noexcept

Construct a unique pointer by value.

Takes ownership of the passed pointer.

template<class T> template<class ... Args>
Corrade::Containers::Pointer<T>::Pointer(Corrade::InPlaceInitT, Args && ... args) explicit

Construct a unique pointer in-place.

Allocates a new object by passing args to its constructor.

template<class T> template<class U, class = typename std::enable_if<std::is_base_of<T, U>::value>::type>
Corrade::Containers::Pointer<T>::Pointer(Pointer<U>&& other) noexcept

Construct a unique pointer from another of a derived type.

Expects that T is a base of U. In order to avoid resource leaks when deleting through the base pointer, either U is expected to be trivially destructible or T is expected to have a virtual destructor. For downcasting (base to derived) use pointerCast(). Calls release() on other.

template<class T> template<class U, class = decltype(Implementation::PointerConverter<T, U>::from(std::declval<U && >()))>
Corrade::Containers::Pointer<T>::Pointer(U&& other) noexcept

Construct a unique pointer from external representation.

template<class T> template<class U, class = decltype(Implementation::PointerConverter<T, U>::to(std::declval<Pointer<T> && >()))>
Corrade::Containers::Pointer<T>::operator U() &&

Convert the unique pointer to external representation.

template<class T>
Corrade::Containers::Pointer<T>::~Pointer()

Destructor.

Calls delete on the stored pointer. In order to avoid resource leaks when deleting the pointer, the type is expected to be complete when calling the destructor. See Usage with incomplete types for more information.

template<class T>
Corrade::Containers::Pointer<T>::operator bool() const explicit

Whether the pointer is non-null.

Returns false if stored pointer is nullptr, true otherwise.

template<class T>
bool Corrade::Containers::Pointer<T>::operator==(std::nullptr_t) const

Equality comparison to a null pointer.

Returns true if the poiner is nullptr, false otherwise.

template<class T>
bool Corrade::Containers::Pointer<T>::operator!=(std::nullptr_t) const

Non-equality comparison to a null pointer.

Returns false if the pointer is nullptr, false otherwise.

template<class T>
T* Corrade::Containers::Pointer<T>::get()

Underlying pointer value.

template<class T>
const T* Corrade::Containers::Pointer<T>::get() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
T* Corrade::Containers::Pointer<T>::operator->()

Access the underlying pointer.

Expects that the pointer is not nullptr.

template<class T>
const T* Corrade::Containers::Pointer<T>::operator->() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
T& Corrade::Containers::Pointer<T>::operator*()

Access the underlying pointer.

Expects that the pointer is not nullptr.

template<class T>
const T& Corrade::Containers::Pointer<T>::operator*() const

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<class T>
void Corrade::Containers::Pointer<T>::reset(T* pointer = nullptr)

Reset the pointer to a new value.

Calls delete on the previously stored pointer and replaces it with pointer. In order to avoid resource leaks when deleting the pointer, the type is expected to be complete when calling this function. See Usage with incomplete types for more information.

template<class T> template<class ... Args>
T& Corrade::Containers::Pointer<T>::emplace(Args && ... args)

Emplace a new value.

Calls delete on the previously stored pointer and allocates a new object by passing args to its constructor.

template<class T> template<class U, class ... Args>
U& Corrade::Containers::Pointer<T>::emplace(Args && ... args) new in Git master

Emplace a new value of a derived type.

Calls delete on the previously stored pointer and allocates a new object of type U by passing args to its constructor. In order to avoid resource leaks when deleting through the base pointer, either U is expected to be trivially destructible or T is expected to have a virtual destructor.

template<class T>
T* Corrade::Containers::Pointer<T>::release()

Release the pointer ownership.

Resets the stored pointer to nullptr, returning the previous value.

template<class T> template<class T>
bool operator==(std::nullptr_t, const Pointer<T>& b)

Equality comparison of a null pointer and an unique pointer.

See Pointer::operator==(std::nullptr_t) const for more information.

template<class T> template<class T>
bool operator!=(std::nullptr_t, const Pointer<T>& b)

Non-euality comparison of a null pointer and an unique pointer.

See Pointer::operator!=(std::nullptr_t) const for more information.

template<class T> template<class T>
Pointer<T> pointer(T* pointer)

Make a unique pointer.

Convenience alternative to Pointer::Pointer(T*). The following two lines are equivalent:

std::string* ptr = ;

auto a = Containers::Pointer<std::string>{ptr};
auto b = Containers::pointer(ptr);

template<class T> template<class T>
auto pointer(T&& other)

Make a unique pointer from external representation.

template<class T> template<class U, class T>
Pointer<U> pointerCast(Pointer<T>&& pointer)

Downcast a pointer.

While upcasting (derived to base) is handled implicitly with Pointer::Pointer(Pointer<U>&&), downcasting needs to be done explicitly. Performs static_cast<U>(), calling Pointer::release() on pointer. You have to ensure the pointer is actually of type U, as only the inheritance relation between T and U is checked at compile time, not the actual type stored in pointer.

Casting with dynamic_cast<U>() is not supported, as it would lead to a destructive behavior in case the instance is not of type U. The standard library provides std::dynamic_pointer_cast() and friends for this case, but they return a std::shared_ptr in order to behave non-destructively.

template<class T> template<class T, class ... Args>
Pointer<T> pointer(Args && ... args)

Make a unique pointer.

Convenience alternative to Pointer::Pointer(InPlaceInitT, Args&&... args), similar to std::make_unique() from C++14. The following two lines are equivalent:

auto a = Containers::Pointer<std::string>{InPlaceInit, 'a', 'b'};
auto b = Containers::pointer<std::string>('a', 'b');

template<class T> template<class T>
Utility::Debug& operator<<(Utility::Debug& debug, const Pointer<T>& value)

Debug output operator.