[libc++] LWG3223 Broken requirements for shared_ptr converting constructors (#93071)
This commit is contained in:
parent
44d4b3b2ee
commit
d868f09705
@ -200,7 +200,7 @@
|
||||
"`3200 <https://wg21.link/LWG3200>`__","``midpoint``\ should not constrain ``T``\ is complete","Prague","|Nothing To Do|",""
|
||||
"`3201 <https://wg21.link/LWG3201>`__","``lerp``\ should be marked as ``noexcept``\ ","Prague","|Complete|",""
|
||||
"`3226 <https://wg21.link/LWG3226>`__","``zoned_time``\ constructor from ``string_view``\ should accept ``zoned_time<Duration2, TimeZonePtr2>``\ ","Prague","","","|chrono|"
|
||||
"`3233 <https://wg21.link/LWG3233>`__","Broken requirements for ``shared_ptr``\ converting constructors","Prague","",""
|
||||
"`3233 <https://wg21.link/LWG3233>`__","Broken requirements for ``shared_ptr``\ converting constructors","Prague","|Complete|","19.0"
|
||||
"`3237 <https://wg21.link/LWG3237>`__","LWG 3038 and 3190 have inconsistent PRs","Prague","|Complete|","16.0"
|
||||
"`3238 <https://wg21.link/LWG3238>`__","Insufficiently-defined behavior of ``std::function``\ deduction guides","Prague","",""
|
||||
"`3242 <https://wg21.link/LWG3242>`__","``std::format``\ : missing rules for ``arg-id``\ in ``width``\ and ``precision``\ ","Prague","|Complete|","14.0","|format|"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
@ -403,6 +403,9 @@ struct __shared_ptr_deleter_ctor_reqs {
|
||||
__well_formed_deleter<_Dp, _Yp*>::value;
|
||||
};
|
||||
|
||||
template <class _Dp, class _Tp>
|
||||
using __shared_ptr_nullptr_deleter_ctor_reqs = _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, nullptr_t> >;
|
||||
|
||||
#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
|
||||
# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
|
||||
#else
|
||||
@ -498,7 +501,7 @@ public:
|
||||
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
template <class _Dp>
|
||||
template <class _Dp, __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp, _Tp>::value, int> = 0 >
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr(nullptr_t __p, _Dp __d) : __ptr_(nullptr) {
|
||||
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
|
||||
try {
|
||||
@ -518,7 +521,7 @@ public:
|
||||
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
template <class _Dp, class _Alloc>
|
||||
template <class _Dp, class _Alloc, __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp, _Tp>::value, int> = 0 >
|
||||
_LIBCPP_HIDE_FROM_ABI shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) : __ptr_(nullptr) {
|
||||
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
|
||||
try {
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "test_macros.h"
|
||||
#include "deleter_types.h"
|
||||
|
||||
#include "types.h"
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
@ -28,6 +29,25 @@ struct A
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
// LWG 3233. Broken requirements for shared_ptr converting constructors
|
||||
// https://cplusplus.github.io/LWG/issue3233
|
||||
static_assert( std::is_constructible<std::shared_ptr<int>, std::nullptr_t, test_deleter<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, bad_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, no_nullptr_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, no_move_deleter>::value, "");
|
||||
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert( std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, test_deleter<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, bad_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, no_nullptr_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, no_move_deleter>::value, "");
|
||||
|
||||
static_assert( std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, test_deleter<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, bad_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, no_nullptr_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, no_move_deleter>::value, "");
|
||||
#endif
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "test_allocator.h"
|
||||
#include "min_allocator.h"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
@ -28,6 +30,25 @@ struct A
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
// LWG 3233. Broken requirements for shared_ptr converting constructors
|
||||
// https://cplusplus.github.io/LWG/issue3233
|
||||
static_assert( std::is_constructible<std::shared_ptr<int>, std::nullptr_t, test_deleter<int>, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, bad_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, no_nullptr_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, no_move_deleter, test_allocator<int> >::value, "");
|
||||
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert( std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, test_deleter<int>, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, bad_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, no_nullptr_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, no_move_deleter, test_allocator<int> >::value, "");
|
||||
|
||||
static_assert( std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, test_deleter<int>, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, bad_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, no_nullptr_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, no_move_deleter, test_allocator<int> >::value, "");
|
||||
#endif
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
test_allocator_statistics alloc_stats;
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "test_macros.h"
|
||||
#include "deleter_types.h"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
@ -28,38 +30,8 @@ struct A
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
struct bad_ty { };
|
||||
|
||||
struct bad_deleter
|
||||
{
|
||||
void operator()(bad_ty) { }
|
||||
};
|
||||
|
||||
struct no_move_deleter
|
||||
{
|
||||
no_move_deleter(no_move_deleter const&) = delete;
|
||||
no_move_deleter(no_move_deleter &&) = delete;
|
||||
void operator()(int*) { }
|
||||
};
|
||||
|
||||
static_assert(!std::is_move_constructible<no_move_deleter>::value, "");
|
||||
|
||||
struct Base { };
|
||||
struct Derived : Base { };
|
||||
|
||||
template<class T>
|
||||
class MoveDeleter
|
||||
{
|
||||
MoveDeleter();
|
||||
MoveDeleter(MoveDeleter const&);
|
||||
public:
|
||||
MoveDeleter(MoveDeleter&&) {}
|
||||
|
||||
explicit MoveDeleter(int) {}
|
||||
|
||||
void operator()(T* ptr) { delete ptr; }
|
||||
};
|
||||
|
||||
// LWG 3233. Broken requirements for shared_ptr converting constructors
|
||||
// https://cplusplus.github.io/LWG/issue3233
|
||||
// https://llvm.org/PR60258
|
||||
// Invalid constructor SFINAE for std::shared_ptr's array ctors
|
||||
static_assert( std::is_constructible<std::shared_ptr<int>, int*, test_deleter<int> >::value, "");
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "test_allocator.h"
|
||||
#include "min_allocator.h"
|
||||
|
||||
#include "types.h"
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
@ -28,38 +29,8 @@ struct A
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
struct bad_ty { };
|
||||
|
||||
struct bad_deleter
|
||||
{
|
||||
void operator()(bad_ty) { }
|
||||
};
|
||||
|
||||
struct no_move_deleter
|
||||
{
|
||||
no_move_deleter(no_move_deleter const&) = delete;
|
||||
no_move_deleter(no_move_deleter &&) = delete;
|
||||
void operator()(int*) { }
|
||||
};
|
||||
|
||||
static_assert(!std::is_move_constructible<no_move_deleter>::value, "");
|
||||
|
||||
struct Base { };
|
||||
struct Derived : Base { };
|
||||
|
||||
template<class T>
|
||||
class MoveDeleter
|
||||
{
|
||||
MoveDeleter();
|
||||
MoveDeleter(MoveDeleter const&);
|
||||
public:
|
||||
MoveDeleter(MoveDeleter&&) {}
|
||||
|
||||
explicit MoveDeleter(int) {}
|
||||
|
||||
void operator()(T* ptr) { delete ptr; }
|
||||
};
|
||||
|
||||
// LWG 3233. Broken requirements for shared_ptr converting constructors
|
||||
// https://cplusplus.github.io/LWG/issue3233
|
||||
// https://llvm.org/PR60258
|
||||
// Invalid constructor SFINAE for std::shared_ptr's array ctors
|
||||
static_assert( std::is_constructible<std::shared_ptr<int>, int*, test_deleter<int>, test_allocator<int> >::value, "");
|
||||
|
@ -0,0 +1,49 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef TEST_STD_UTILITIES_MEMORY_UTIL_SMARTPTR_SHARED_CONST_TYPES_H
|
||||
#define TEST_STD_UTILITIES_MEMORY_UTIL_SMARTPTR_SHARED_CONST_TYPES_H
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
struct bad_ty {};
|
||||
|
||||
struct bad_deleter {
|
||||
void operator()(bad_ty) {}
|
||||
};
|
||||
|
||||
struct no_move_deleter {
|
||||
no_move_deleter(no_move_deleter const&) = delete;
|
||||
no_move_deleter(no_move_deleter&&) = delete;
|
||||
void operator()(int*) {}
|
||||
};
|
||||
|
||||
static_assert(!std::is_move_constructible<no_move_deleter>::value, "");
|
||||
|
||||
struct no_nullptr_deleter {
|
||||
void operator()(int*) const {}
|
||||
void operator()(std::nullptr_t) const = delete;
|
||||
};
|
||||
|
||||
struct Base {};
|
||||
struct Derived : Base {};
|
||||
|
||||
template <class T>
|
||||
class MoveDeleter {
|
||||
MoveDeleter();
|
||||
MoveDeleter(MoveDeleter const&);
|
||||
|
||||
public:
|
||||
MoveDeleter(MoveDeleter&&) {}
|
||||
|
||||
explicit MoveDeleter(int) {}
|
||||
|
||||
void operator()(T* ptr) { delete ptr; }
|
||||
};
|
||||
|
||||
#endif // TEST_STD_UTILITIES_MEMORY_UTIL_SMARTPTR_SHARED_CONST_TYPES_H
|
Loading…
x
Reference in New Issue
Block a user