Skip to content

Commit

Permalink
[libc++] Remove the allocator<const T> extension (llvm#102655)
Browse files Browse the repository at this point in the history
In LLVM 19 removed the extension with an opt-in macro. This finally
removes that option too and removes a few `const_cast`s where I know
that they exist only to support this extension.
  • Loading branch information
philnik777 authored Aug 15, 2024
1 parent 6cbd96e commit 85da39d
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 106 deletions.
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

0 comments on commit 85da39d

Please sign in to comment.