diff options
Diffstat (limited to 'libcxx/include/memory')
-rw-r--r-- | libcxx/include/memory | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/libcxx/include/memory b/libcxx/include/memory index efb10c8fd25b..62235cf72b35 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -810,10 +810,35 @@ public: }; #endif +// This class provides a non-trivial default constructor to the class that derives from it +// if the condition is satisfied. +// +// The second template parameter exists to allow giving a unique type to __non_trivial_if, +// which makes it possible to avoid breaking the ABI when making this a base class of an +// existing class. Without that, imagine we have classes D1 and D2, both of which used to +// have no base classes, but which now derive from __non_trivial_if. The layout of a class +// that inherits from both D1 and D2 will change because the two __non_trivial_if base +// classes are not allowed to share the same address. +// +// By making those __non_trivial_if base classes unique, we work around this problem and +// it is safe to start deriving from __non_trivial_if in existing classes. +template <bool _Cond, class _Unique> +struct __non_trivial_if { }; + +template <class _Unique> +struct __non_trivial_if<true, _Unique> { + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR __non_trivial_if() _NOEXCEPT { } +}; + // allocator +// +// Note: For ABI compatibility between C++20 and previous standards, we make +// allocator<void> trivial in C++20. template <class _Tp> class _LIBCPP_TEMPLATE_VIS allocator + : private __non_trivial_if<!is_void<_Tp>::value, allocator<_Tp> > { public: typedef size_t size_type; @@ -823,7 +848,7 @@ public: typedef true_type is_always_equal; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 - allocator() _NOEXCEPT { } + allocator() _NOEXCEPT _LIBCPP_DEFAULT template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -895,6 +920,7 @@ public: template <class _Tp> class _LIBCPP_TEMPLATE_VIS allocator<const _Tp> + : private __non_trivial_if<!is_void<_Tp>::value, allocator<const _Tp> > { public: typedef size_t size_type; @@ -904,7 +930,7 @@ public: typedef true_type is_always_equal; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 - allocator() _NOEXCEPT { } + allocator() _NOEXCEPT _LIBCPP_DEFAULT template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -2745,7 +2771,6 @@ public: typename enable_if < !is_lvalue_reference<_Dp>::value && - !is_array<_Yp>::value && is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, __nat >::type = __nat()); @@ -2754,7 +2779,6 @@ public: typename enable_if < is_lvalue_reference<_Dp>::value && - !is_array<_Yp>::value && is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, __nat >::type = __nat()); @@ -2795,7 +2819,6 @@ public: template <class _Yp, class _Dp> typename enable_if < - !is_array<_Yp>::value && is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, shared_ptr& >::type @@ -3157,7 +3180,6 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, typename enable_if < !is_lvalue_reference<_Dp>::value && - !is_array<_Yp>::value && is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, __nat >::type) @@ -3170,7 +3192,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, #endif { typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; + typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); __enable_weak_this(__r.get(), __r.get()); } @@ -3183,7 +3205,6 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, typename enable_if < is_lvalue_reference<_Dp>::value && - !is_array<_Yp>::value && is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, __nat >::type) @@ -3196,7 +3217,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, #endif { typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; - typedef __shared_ptr_pointer<_Yp*, + typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, reference_wrapper<typename remove_reference<_Dp>::type>, _AllocT > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT()); @@ -3280,7 +3301,6 @@ template <class _Yp, class _Dp> inline typename enable_if < - !is_array<_Yp>::value && is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, typename shared_ptr<_Tp>::element_type*>::value, shared_ptr<_Tp>& |