diff --git a/include/memory b/include/memory --- a/include/memory +++ b/include/memory @@ -492,6 +492,8 @@ shared_ptr dynamic_pointer_cast(shared_ptr const& r) noexcept; template shared_ptr const_pointer_cast(shared_ptr const& r) noexcept; +template + shared_ptr reinterpret_pointer_cast(shared_ptr const& r) noexcept; // shared_ptr I/O: template @@ -4629,6 +4631,12 @@ return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); } +template +shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT +{ + return shared_ptr<_Tp>(__r, reinterpret_cast<_Tp*>(__r.get())); +} + #ifndef _LIBCPP_NO_RTTI template diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/reinterpret_pointer_cast.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/reinterpret_pointer_cast.pass.cpp new file mode 100644 --- /dev/null +++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cast/reinterpret_pointer_cast.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// shared_ptr + +// template shared_ptr reinterpret_pointer_cast(const shared_ptr& r); + +#include +#include +#include + +#include "test_macros.h" + +struct B +{ + static int count; + + B() {++count;} + B(const B&) {++count;} + virtual ~B() {--count;} +}; + +int B::count = 0; + +struct A + : public B +{ + static int count; + + A() {++count;} + A(const A&) {++count;} + ~A() {--count;} +}; + +int A::count = 0; + +int main(int, char**) +{ + { + const std::shared_ptr pA(new A); + std::shared_ptr pB = std::reinterpret_pointer_cast(pA); + assert(pB.get() == pA.get()); + assert(!pB.owner_before(pA) && !pA.owner_before(pB)); + } + { + const std::shared_ptr pA(new A); + std::shared_ptr pB = std::reinterpret_pointer_cast(pA); + assert(pB.get() == pA.get()); + assert(!pB.owner_before(pA) && !pA.owner_before(pB)); + } + { + const std::shared_ptr pA; + std::shared_ptr pB = std::reinterpret_pointer_cast(pA); + assert(pB.get() == pA.get()); + assert(!pB.owner_before(pA) && !pA.owner_before(pB)); + } + { + const std::shared_ptr pA; + std::shared_ptr pB = std::reinterpret_pointer_cast(pA); + assert(pB.get() == pA.get()); + assert(!pB.owner_before(pA) && !pA.owner_before(pB)); + } + + return 0; +}