diff options
Diffstat (limited to 'include/memory')
-rw-r--r-- | include/memory | 86 |
1 files changed, 70 insertions, 16 deletions
diff --git a/include/memory b/include/memory index df221ffa75108..fd830d7ed2cc5 100644 --- a/include/memory +++ b/include/memory @@ -18,7 +18,7 @@ namespace std { struct allocator_arg_t { }; -constexpr allocator_arg_t allocator_arg = allocator_arg_t(); +inline constexpr allocator_arg_t allocator_arg = allocator_arg_t(); template <class T, class Alloc> struct uses_allocator; @@ -126,9 +126,10 @@ public: template <class U> struct rebind {typedef allocator<U> other;}; - allocator() noexcept; - allocator(const allocator&) noexcept; - template <class U> allocator(const allocator<U>&) noexcept; + constexpr allocator() noexcept; // constexpr in C++20 + constexpr allocator(const allocator&) noexcept; // constexpr in C++20 + template <class U> + constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20 ~allocator(); pointer address(reference x) const noexcept; const_pointer address(const_reference x) const noexcept; @@ -631,6 +632,9 @@ template <class T> struct hash; template <class T, class D> struct hash<unique_ptr<T, D> >; template <class T> struct hash<shared_ptr<T> >; +template <class T, class Alloc> + inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value; + // Pointer safety enum class pointer_safety { relaxed, preferred, strict }; void declare_reachable(void *p); @@ -675,7 +679,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template <class _ValueType> -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY _ValueType __libcpp_relaxed_load(_ValueType const* __value) { #if !defined(_LIBCPP_HAS_NO_THREADS) && \ defined(__ATOMIC_RELAXED) && \ @@ -687,7 +691,7 @@ _ValueType __libcpp_relaxed_load(_ValueType const* __value) { } template <class _ValueType> -inline _LIBCPP_ALWAYS_INLINE +inline _LIBCPP_INLINE_VISIBILITY _ValueType __libcpp_acquire_load(_ValueType const* __value) { #if !defined(_LIBCPP_HAS_NO_THREADS) && \ defined(__ATOMIC_ACQUIRE) && \ @@ -1775,8 +1779,13 @@ public: template <class _Up> struct rebind {typedef allocator<_Up> other;}; - _LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {} - template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + allocator() _NOEXCEPT {} + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + allocator(const allocator<_Up>&) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT {return _VSTD::addressof(__x);} _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT @@ -1787,10 +1796,10 @@ public: if (__n > max_size()) __throw_length_error("allocator<T>::allocate(size_t n)" " 'n' exceeds maximum supported size"); - return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp))); + return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp))); } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT - {_VSTD::__libcpp_deallocate((void*)__p);} + {_VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return size_type(~0) / sizeof(_Tp);} #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) @@ -1874,8 +1883,13 @@ public: template <class _Up> struct rebind {typedef allocator<_Up> other;}; - _LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {} - template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + allocator() _NOEXCEPT {} + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + allocator(const allocator<_Up>&) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT {return _VSTD::addressof(__x);} _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) @@ -1883,10 +1897,10 @@ public: if (__n > max_size()) __throw_length_error("allocator<const T>::allocate(size_t n)" " 'n' exceeds maximum supported size"); - return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp))); + return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp))); } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT - {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p));} + {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __alignof(_Tp));} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return size_type(~0) / sizeof(_Tp);} #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) @@ -1989,6 +2003,7 @@ public: }; template <class _Tp> +_LIBCPP_NO_CFI pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { @@ -2000,7 +2015,28 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT __n = __m; while (__n > 0) { +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + if (__is_overaligned_for_new(__alignof(_Tp))) + { + std::align_val_t __al = + std::align_val_t(std::alignment_of<_Tp>::value); + __r.first = static_cast<_Tp*>(::operator new( + __n * sizeof(_Tp), __al, nothrow)); + } else { + __r.first = static_cast<_Tp*>(::operator new( + __n * sizeof(_Tp), nothrow)); + } +#else + if (__is_overaligned_for_new(__alignof(_Tp))) + { + // Since aligned operator new is unavailable, return an empty + // buffer rather than one with invalid alignment. + return __r; + } + __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow)); +#endif + if (__r.first) { __r.second = __n; @@ -2013,7 +2049,10 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY -void return_temporary_buffer(_Tp* __p) _NOEXCEPT {::operator delete(__p);} +void return_temporary_buffer(_Tp* __p) _NOEXCEPT +{ + _VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp)); +} #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) template <class _Tp> @@ -3444,7 +3483,7 @@ public: virtual const char* what() const _NOEXCEPT; }; -_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_bad_weak_ptr() { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -4754,8 +4793,13 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT { +#if _LIBCPP_STD_VER <= 11 typedef typename common_type<_Tp*, _Up*>::type _Vp; return less<_Vp>()(__x.get(), __y.get()); +#else + return less<>()(__x.get(), __y.get()); +#endif + } template<class _Tp, class _Up> @@ -5594,6 +5638,16 @@ struct __temp_value { }; #endif +template<typename _Alloc, typename = void, typename = void> +struct __is_allocator : false_type {}; + +template<typename _Alloc> +struct __is_allocator<_Alloc, + typename __void_t<typename _Alloc::value_type>::type, + typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type + > + : true_type {}; + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS |