diff --git a/libcxx/include/__memory/utilities.h b/libcxx/include/__memory/utilities.h index ccbfbe78966c4a..aac3d11cab574a 100644 --- a/libcxx/include/__memory/utilities.h +++ b/libcxx/include/__memory/utilities.h @@ -48,8 +48,9 @@ struct __allocation_guard { using _Pointer = typename allocator_traits<_Alloc>::pointer; using _Size = typename allocator_traits<_Alloc>::size_type; + template // we perform the allocator conversion inside the constructor _LIBCPP_HIDE_FROM_ABI - explicit __allocation_guard(_Alloc __alloc, _Size __n) + explicit __allocation_guard(_AllocT __alloc, _Size __n) : __alloc_(_VSTD::move(__alloc)) , __n_(__n) , __ptr_(allocator_traits<_Alloc>::allocate(__alloc_, __n_)) // initialization order is important diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.explicit_conversion.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.explicit_conversion.pass.cpp new file mode 100644 index 00000000000000..446daa1ec9f2a5 --- /dev/null +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.explicit_conversion.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Make sure that std::allocate_shared works with an allocator type that is +// only explicitly convertible from another specialization of itself. + +#include +#include +#include + +template +struct ExplicitAllocator { + ExplicitAllocator() = default; + template + explicit ExplicitAllocator(ExplicitAllocator) { } + + using value_type = T; + T* allocate(std::size_t n) { return std::allocator().allocate(n); } + void deallocate(T* ptr, std::size_t n) { return std::allocator().deallocate(ptr, n); } +}; + +int main(int, char**) { + std::shared_ptr ptr = std::allocate_shared(ExplicitAllocator(), 0); + (void)ptr; + + return 0; +}