#include <Corrade/Containers/Pointer.h>
template<class T>
Pointer class
Lightweight unique pointer.
An alternative to std::T
, calling delete
on it on destruction. The pointer() convenience function also provides an equivalent for C++14 std::
Compared to std::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::
Unlike std::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::
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::#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::Pointer(Pointer<U>&& other) noexcept
enable_if<std:: is_base_of<T, U>::value>::type> - Construct a unique pointer from another of a derived type.
-
template<class U, class = decltype(Implementation::PointerConverter<T, U>::from(std::Pointer(U&& other) noexcept
declval<U && >()))> - 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::operator U() &&
declval<Pointer<T> && >()))> - 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::
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::
template<class T>
template<class T>
Pointer<T> pointer(T* pointer)
Make a unique pointer.
Convenience alternative to Pointer::
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::static_cast<U>()
, calling Pointer::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::
template<class T>
template<class T, class ... Args>
Pointer<T> pointer(Args && ... args)
Make a unique pointer.
Convenience alternative to Pointer::
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.