diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -450,6 +450,11 @@ template bool owner_before(weak_ptr const& b) const noexcept; }; +template +shared_ptr(weak_ptr) -> shared_ptr; +template +shared_ptr(unique_ptr) -> shared_ptr; + // shared_ptr comparisons: template bool operator==(shared_ptr const& a, shared_ptr const& b) noexcept; @@ -548,6 +553,9 @@ template bool owner_before(weak_ptr const& b) const noexcept; }; +template +weak_ptr(shared_ptr) -> weak_ptr; + // weak_ptr specialized algorithms: template void swap(weak_ptr& a, weak_ptr& b) noexcept; @@ -3965,6 +3973,12 @@ template friend class _LIBCPP_TEMPLATE_VIS weak_ptr; }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template +shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; +template +shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; +#endif template inline @@ -4765,6 +4779,11 @@ template friend class _LIBCPP_TEMPLATE_VIS shared_ptr; }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template +weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; +#endif + template inline _LIBCPP_CONSTEXPR diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/deduction.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/deduction.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/deduction.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template class shared_ptr + +// shared_ptr(weak_ptr) -> shared_ptr +// shared_ptr(unique_ptr) -> shared_ptr + +#include +#include + +#include "test_macros.h" + +struct A {}; + +struct D { + void operator()(void*) const {} +}; + +int main(int, char**) +{ + { + std::shared_ptr s0(new A); + std::weak_ptr w = s0; + auto s = std::shared_ptr(w); + ASSERT_SAME_TYPE(decltype(s), std::shared_ptr); + assert(s0.use_count() == 2); + assert(s.use_count() == 2); + assert(s0.get() == s.get()); + } + { + std::unique_ptr u(new A); + A* const uPointee = u.get(); + std::shared_ptr s = std::move(u); + ASSERT_SAME_TYPE(decltype(s), std::shared_ptr); + assert(u == nullptr); + assert(s.get() == uPointee); + } + { + std::unique_ptr u(new A, D{}); + A* const uPointee = u.get(); + std::shared_ptr s(std::move(u)); + ASSERT_SAME_TYPE(decltype(s), std::shared_ptr); + assert(u == nullptr); + assert(s.get() == uPointee); + } + + return 0; +} diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_deduction.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_deduction.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.weak/util.smartptr.weak.const/shared_ptr_deduction.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: libcpp-no-deduction-guides + +// template class weak_ptr + +// weak_ptr(shared_ptr) -> weak_ptr + +#include +#include + +#include "test_macros.h" + +struct A {}; + +int main(int, char**) +{ + std::shared_ptr s(new A); + auto w = std::weak_ptr(s); + ASSERT_SAME_TYPE(decltype(w), std::weak_ptr); + assert(!w.expired()); + assert(w.use_count() == 1); + assert(w.lock().get() == s.get()); + + return 0; +}