C++ Logo

std-proposals

Advanced search

pointer_cast for unique_ptr

From: connor horman <chorman64_at_[hidden]>
Date: Sun, 27 Dec 2020 22:15:16 -0500
This came up in some code I'm helping with, but I noticed that there are
not overloads of *_pointer_cast for unique_ptr. This seems like a potential
failing in the spec, so I propose to add these overloads, and the machinery
to do so.

To std::default_deleter<T>, add a member template<typename U> rebind =
default_deleter<U>;
Add a similar member to the default_deleter<T[]>.
Additionally, modify the constructor of default_deleter to participate in
overload resolution if any of the following is true:
- U is a (possibly virtual) base class of T (does this need to allow
inaccessible base classes, or is that not permitted by an implicit
conversion),
- T is an accessible (possibly virtual) base class of U, in a context
unrelated to both T and U,
- U is (possibly-differently cv-qualified) T, or
- Both T and U are polymorphic types and U has a virtual destructor.
Such that the constructor is explicit iff T* is implicitly convertible to U*
Likewise, permit any qualification conversion in the constructor of the T[]
specialization (constructor is explicit if U(*)[] is less qualified then
T(*)[])

The, add all of the following overloads to the <memory> header, as follows:

Let REBIND_DELETER be an exposition-only template alias, where,
REBIND_DELETER<D,U> is typename D::template rebind<U> if that type is
well-formed, otherwise, if D is Deleter<T,Rest...> for some template
Deleter and some list of types Rest..., REBIND_DELETER<D,U> is
Deleter<U,Rest...>, otherwise, the type is not well-formed.

template<typename U,typename T,typename D>
std::unique_ptr<U,REBIND_DELETER<D,U>>
const_pointer_cast(std::unique_ptr<T,D>&& ptr)
- Performs a type qualification conversion of a unique_ptr, as though by
const_cast
- Only participates in overload resolution if REBIND_DELETER<D,U> is well
formed and is constructible from D,
 typename std::pointer_traits<typename D::pointer>::template rebind<U> is
implicitly convertible to typename REBIND_DELETER<D,U>::pointer, and the
conversion from T* to U* may be performed by a valid const_cast
- After this call, ptr does not own an object.

template<typename U,typename T,typename D>
std::unique_ptr<U,REBIND_DELETER<D,U>>
staitic_pointer_cast(std::unique_ptr<T,D>&& ptr)
- Performs a type qualification conversion of a unique_ptr, as though by
const_cast
- Only participates in overload resolution if REBIND_DELETER<D,U> is well
formed and constructible from D,
 typename std::pointer_traits<typename D::pointer>::template rebind<U> is
implicitly convertible to typename REBIND_DELETER<D,U>::pointer, and the
conversion from T* to U* may be performed by a valid static_cast
- After this call, ptr does not own an object.

template<typename U,typename T,typename D>
std::unique_ptr<U,REBIND_DELETER<D,U>>
dynamic_pointer_cast(std::unique_ptr<T,D>&& ptr)
- Performs a type qualification conversion of a unique_ptr, as though by
const_cast
- Only participates in overload resolution if REBIND_DELETER<D,U> is well
formed and constructible from D,
 typename std::pointer_traits<typename D::pointer>::template rebind<U> is
implicitly convertible to typename REBIND_DELETER<D,U>::pointer, the
conversion from T* to U* may be performed by a valid dynamic_cast
- If the dynamic_cast succeeds, ptr will not own an object. Otherwise, ptr
is left in an unmodified state, and the result does not own an object.

Received on 2020-12-27 21:16:23