Skip to content

[libc++] Remove the allocator<const T> extension #102655

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libcxx/docs/ReleaseNotes/20.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Deprecations and Removals
``_LIBCPP_ENABLE_REMOVED_WEEKDAY_RELATIONAL_OPERATORS`` macro that was used to re-enable this extension will be
ignored in LLVM 20.

- TODO: The ``_LIBCPP_ENABLE_REMOVED_ALLOCATOR_CONST`` macro will no longer have an effect.
- The ``_LIBCPP_ENABLE_REMOVED_ALLOCATOR_CONST`` macro no longer has any effect. ``std::allocator<const T>`` is not supported as an extension anymore, please migrate any code that uses e.g. ``std::vector<const T>`` to be standards conforming.

Upcoming Deprecations and Removals
----------------------------------
Expand Down
95 changes: 0 additions & 95 deletions libcxx/include/__memory/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,6 @@ class _LIBCPP_TEMPLATE_VIS allocator<void> {
typedef allocator<_Up> other;
};
};

// TODO(LLVM 20): Remove the escape hatch
# ifdef _LIBCPP_ENABLE_REMOVED_ALLOCATOR_CONST
template <>
class _LIBCPP_TEMPLATE_VIS allocator<const void> {
public:
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void value_type;

template <class _Up>
struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
typedef allocator<_Up> other;
};
};
# endif // _LIBCPP_ENABLE_REMOVED_ALLOCATOR_CONST
#endif // _LIBCPP_STD_VER <= 17

// This class provides a non-trivial default constructor to the class that derives from it
Expand Down Expand Up @@ -171,85 +155,6 @@ class _LIBCPP_TEMPLATE_VIS allocator : private __non_trivial_if<!is_void<_Tp>::v
#endif
};

// TODO(LLVM 20): Remove the escape hatch
#ifdef _LIBCPP_ENABLE_REMOVED_ALLOCATOR_CONST
template <class _Tp>
class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
: private __non_trivial_if<!is_void<_Tp>::value, allocator<const _Tp> > {
static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types");

public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef const _Tp value_type;
typedef true_type propagate_on_container_move_assignment;
# if _LIBCPP_STD_VER <= 23 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX23 typedef true_type is_always_equal;
# endif

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator() _NOEXCEPT = default;

template <class _Up>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator(const allocator<_Up>&) _NOEXCEPT {}

_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const _Tp* allocate(size_t __n) {
if (__n > allocator_traits<allocator>::max_size(*this))
__throw_bad_array_new_length();
if (__libcpp_is_constant_evaluated()) {
return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
} else {
return static_cast<const _Tp*>(std::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
}

# if _LIBCPP_STD_VER >= 23
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr allocation_result<const _Tp*> allocate_at_least(size_t __n) {
return {allocate(__n), __n};
}
# endif

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void deallocate(const _Tp* __p, size_t __n) {
if (__libcpp_is_constant_evaluated()) {
::operator delete(const_cast<_Tp*>(__p));
} else {
std::__libcpp_deallocate((void*)const_cast<_Tp*>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
}
}

// C++20 Removed members
# if _LIBCPP_STD_VER <= 17
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;

template <class _Up>
struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
typedef allocator<_Up> other;
};

_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI const_pointer address(const_reference __x) const _NOEXCEPT {
return std::addressof(__x);
}

_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX17 const _Tp* allocate(size_t __n, const void*) {
return allocate(__n);
}

_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
return size_type(~0) / sizeof(_Tp);
}

template <class _Up, class... _Args>
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI void construct(_Up* __p, _Args&&... __args) {
::new ((void*)__p) _Up(std::forward<_Args>(__args)...);
}

_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI void destroy(pointer __p) { __p->~_Tp(); }
# endif
};
#endif // _LIBCPP_ENABLE_REMOVED_ALLOCATOR_CONST

template <class _Tp, class _Up>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {
Expand Down
16 changes: 6 additions & 10 deletions libcxx/include/__memory/uninitialized_algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,17 +562,13 @@ struct __allocator_has_trivial_copy_construct<allocator<_Type>, _Type> : true_ty

template <class _Alloc,
class _In,
class _RawTypeIn = __remove_const_t<_In>,
class _Out,
__enable_if_t<
// using _RawTypeIn because of the allocator<T const> extension
is_trivially_copy_constructible<_RawTypeIn>::value && is_trivially_copy_assignable<_RawTypeIn>::value &&
is_same<__remove_const_t<_In>, __remove_const_t<_Out> >::value &&
__allocator_has_trivial_copy_construct<_Alloc, _RawTypeIn>::value,
int> = 0>
__enable_if_t<is_trivially_copy_constructible<_In>::value && is_trivially_copy_assignable<_In>::value &&
is_same<__remove_const_t<_In>, __remove_const_t<_Out> >::value &&
__allocator_has_trivial_copy_construct<_Alloc, _In>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Out*
__uninitialized_allocator_copy_impl(_Alloc&, _In* __first1, _In* __last1, _Out* __first2) {
// TODO: Remove the const_cast once we drop support for std::allocator<T const>
if (__libcpp_is_constant_evaluated()) {
while (__first1 != __last1) {
std::__construct_at(std::__to_address(__first2), *__first1);
Expand All @@ -581,7 +577,7 @@ __uninitialized_allocator_copy_impl(_Alloc&, _In* __first1, _In* __last1, _Out*
}
return __first2;
} else {
return std::copy(__first1, __last1, const_cast<_RawTypeIn*>(__first2));
return std::copy(__first1, __last1, __first2);
}
}

Expand Down Expand Up @@ -642,7 +638,7 @@ __uninitialized_allocator_relocate(_Alloc& __alloc, _Tp* __first, _Tp* __last, _
__guard.__complete();
std::__allocator_destroy(__alloc, __first, __last);
} else {
__builtin_memcpy(const_cast<__remove_const_t<_Tp>*>(__result), __first, sizeof(_Tp) * (__last - __first));
__builtin_memcpy(__result, __first, sizeof(_Tp) * (__last - __first));
}
}

Expand Down
Loading