// -*- C++ -*- //===-------------------------- memory ------------------------------------===// // // 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 _LIBCPP_MEMORY #define _LIBCPP_MEMORY /* memory synopsis namespace std { struct allocator_arg_t { }; inline constexpr allocator_arg_t allocator_arg = allocator_arg_t(); template struct uses_allocator; template struct pointer_traits { typedef Ptr pointer; typedef
element_type; typedef
difference_type; template using rebind =
; static pointer pointer_to(
); }; template struct pointer_traits { typedef T* pointer; typedef T element_type; typedef ptrdiff_t difference_type; template using rebind = U*; static pointer pointer_to(
) noexcept; // constexpr in C++20 }; template constexpr T* to_address(T* p) noexcept; // C++20 template constexpr auto to_address(const Ptr& p) noexcept; // C++20 template struct allocator_traits { typedef Alloc allocator_type; typedef typename allocator_type::value_type value_type; typedef Alloc::pointer | value_type* pointer; typedef Alloc::const_pointer | pointer_traits::rebind const_pointer; typedef Alloc::void_pointer | pointer_traits::rebind void_pointer; typedef Alloc::const_void_pointer | pointer_traits::rebind const_void_pointer; typedef Alloc::difference_type | pointer_traits::difference_type difference_type; typedef Alloc::size_type | make_unsigned::type size_type; typedef Alloc::propagate_on_container_copy_assignment | false_type propagate_on_container_copy_assignment; typedef Alloc::propagate_on_container_move_assignment | false_type propagate_on_container_move_assignment; typedef Alloc::propagate_on_container_swap | false_type propagate_on_container_swap; typedef Alloc::is_always_equal | is_empty is_always_equal; template using rebind_alloc = Alloc::rebind::other | Alloc; template using rebind_traits = allocator_traits>; static pointer allocate(allocator_type& a, size_type n); // constexpr and [[nodiscard]] in C++20 static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20 static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20 template static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20 template static void destroy(allocator_type& a, T* p); // constexpr in C++20 static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20 static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20 }; template <> class allocator // deprecated in C++17, removed in C++20 { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind {typedef allocator<_Up> other;}; }; template class allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T* pointer; // deprecated in C++17, removed in C++20 typedef const T* const_pointer; // deprecated in C++17, removed in C++20 typedef typename add_lvalue_reference::type reference; // deprecated in C++17, removed in C++20 typedef typename add_lvalue_reference::type const_reference; // deprecated in C++17, removed in C++20 typedef T value_type; template struct rebind {typedef allocator other;}; // deprecated in C++17, removed in C++20 typedef true_type propagate_on_container_move_assignment; typedef true_type is_always_equal; constexpr allocator() noexcept; // constexpr in C++20 constexpr allocator(const allocator&) noexcept; // constexpr in C++20 template constexpr allocator(const allocator&) noexcept; // constexpr in C++20 ~allocator(); // constexpr in C++20 pointer address(reference x) const noexcept; // deprecated in C++17, removed in C++20 const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20 T* allocate(size_t n, const void* hint); // deprecated in C++17, removed in C++20 T* allocate(size_t n); // constexpr in C++20 void deallocate(T* p, size_t n) noexcept; // constexpr in C++20 size_type max_size() const noexcept; // deprecated in C++17, removed in C++20 template void construct(U* p, Args&&... args); // deprecated in C++17, removed in C++20 template void destroy(U* p); // deprecated in C++17, removed in C++20 }; template bool operator==(const allocator&, const allocator&) noexcept; // constexpr in C++20 template bool operator!=(const allocator&, const allocator&) noexcept; // constexpr in C++20 template class raw_storage_iterator : public iterator // purposefully not C++03 { public: explicit raw_storage_iterator(OutputIterator x); raw_storage_iterator& operator*(); raw_storage_iterator& operator=(const T& element); raw_storage_iterator& operator++(); raw_storage_iterator operator++(int); }; template pair get_temporary_buffer(ptrdiff_t n) noexcept; template void return_temporary_buffer(T* p) noexcept; template T* addressof(T& r) noexcept; template T* addressof(const T&& r) noexcept = delete; template ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); template ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); template void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); template ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); template constexpr T* construct_at(T* location, Args&& ...args); // since C++20 template void destroy_at(T* location); // constexpr in C++20 template void destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20 template ForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20 template ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); template pair uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); template void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); template ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); template void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); template ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); template struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17 template class auto_ptr // deprecated in C++11, removed in C++17 { public: typedef X element_type; explicit auto_ptr(X* p =0) throw(); auto_ptr(auto_ptr&) throw(); template auto_ptr(auto_ptr&) throw(); auto_ptr& operator=(auto_ptr&) throw(); template auto_ptr& operator=(auto_ptr&) throw(); auto_ptr& operator=(auto_ptr_ref r) throw(); ~auto_ptr() throw(); typename add_lvalue_reference::type operator*() const throw(); X* operator->() const throw(); X* get() const throw(); X* release() throw(); void reset(X* p =0) throw(); auto_ptr(auto_ptr_ref) throw(); template operator auto_ptr_ref() throw(); template operator auto_ptr() throw(); }; template struct default_delete { constexpr default_delete() noexcept = default; template default_delete(const default_delete&) noexcept; void operator()(T*) const noexcept; }; template struct default_delete { constexpr default_delete() noexcept = default; void operator()(T*) const noexcept; template void operator()(U*) const = delete; }; template > class unique_ptr { public: typedef see below pointer; typedef T element_type; typedef D deleter_type; // constructors constexpr unique_ptr() noexcept; explicit unique_ptr(pointer p) noexcept; unique_ptr(pointer p, see below d1) noexcept; unique_ptr(pointer p, see below d2) noexcept; unique_ptr(unique_ptr&& u) noexcept; unique_ptr(nullptr_t) noexcept : unique_ptr() { } template unique_ptr(unique_ptr&& u) noexcept; template unique_ptr(auto_ptr&& u) noexcept; // removed in C++17 // destructor ~unique_ptr(); // assignment unique_ptr& operator=(unique_ptr&& u) noexcept; template unique_ptr& operator=(unique_ptr&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; // observers typename add_lvalue_reference::type operator*() const; pointer operator->() const noexcept; pointer get() const noexcept; deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept; explicit operator bool() const noexcept; // modifiers pointer release() noexcept; void reset(pointer p = pointer()) noexcept; void swap(unique_ptr& u) noexcept; }; template class unique_ptr { public: typedef implementation-defined pointer; typedef T element_type; typedef D deleter_type; // constructors constexpr unique_ptr() noexcept; explicit unique_ptr(pointer p) noexcept; unique_ptr(pointer p, see below d) noexcept; unique_ptr(pointer p, see below d) noexcept; unique_ptr(unique_ptr&& u) noexcept; unique_ptr(nullptr_t) noexcept : unique_ptr() { } // destructor ~unique_ptr(); // assignment unique_ptr& operator=(unique_ptr&& u) noexcept; unique_ptr& operator=(nullptr_t) noexcept; // observers T& operator[](size_t i) const; pointer get() const noexcept; deleter_type& get_deleter() noexcept; const deleter_type& get_deleter() const noexcept; explicit operator bool() const noexcept; // modifiers pointer release() noexcept; void reset(pointer p = pointer()) noexcept; void reset(nullptr_t) noexcept; template void reset(U) = delete; void swap(unique_ptr& u) noexcept; }; template void swap(unique_ptr& x, unique_ptr& y) noexcept; template bool operator==(const unique_ptr& x, const unique_ptr& y); template bool operator!=(const unique_ptr& x, const unique_ptr& y); template bool operator<(const unique_ptr& x, const unique_ptr& y); template bool operator<=(const unique_ptr& x, const unique_ptr& y); template bool operator>(const unique_ptr& x, const unique_ptr& y); template bool operator>=(const unique_ptr& x, const unique_ptr& y); template bool operator==(const unique_ptr& x, nullptr_t) noexcept; template bool operator==(nullptr_t, const unique_ptr& y) noexcept; template bool operator!=(const unique_ptr& x, nullptr_t) noexcept; template bool operator!=(nullptr_t, const unique_ptr& y) noexcept; template bool operator<(const unique_ptr& x, nullptr_t); template bool operator<(nullptr_t, const unique_ptr& y); template bool operator<=(const unique_ptr& x, nullptr_t); template bool operator<=(nullptr_t, const unique_ptr& y); template bool operator>(const unique_ptr& x, nullptr_t); template bool operator>(nullptr_t, const unique_ptr& y); template bool operator>=(const unique_ptr& x, nullptr_t); template bool operator>=(nullptr_t, const unique_ptr& y); class bad_weak_ptr : public std::exception { bad_weak_ptr() noexcept; }; template unique_ptr make_unique(Args&&... args); // C++14 template unique_ptr make_unique(size_t n); // C++14 template unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] template basic_ostream& operator<< (basic_ostream& os, unique_ptr const& p); template class shared_ptr { public: typedef T element_type; typedef weak_ptr weak_type; // C++17 // constructors: constexpr shared_ptr() noexcept; template explicit shared_ptr(Y* p); template shared_ptr(Y* p, D d); template shared_ptr(Y* p, D d, A a); template shared_ptr(nullptr_t p, D d); template shared_ptr(nullptr_t p, D d, A a); template shared_ptr(const shared_ptr& r, T *p) noexcept; shared_ptr(const shared_ptr& r) noexcept; template shared_ptr(const shared_ptr& r) noexcept; shared_ptr(shared_ptr&& r) noexcept; template shared_ptr(shared_ptr&& r) noexcept; template explicit shared_ptr(const weak_ptr& r); template shared_ptr(auto_ptr&& r); // removed in C++17 template shared_ptr(unique_ptr&& r); shared_ptr(nullptr_t) : shared_ptr() { } // destructor: ~shared_ptr(); // assignment: shared_ptr& operator=(const shared_ptr& r) noexcept; template shared_ptr& operator=(const shared_ptr& r) noexcept; shared_ptr& operator=(shared_ptr&& r) noexcept; template shared_ptr& operator=(shared_ptr&& r); template shared_ptr& operator=(auto_ptr&& r); // removed in C++17 template shared_ptr& operator=(unique_ptr&& r); // modifiers: void swap(shared_ptr& r) noexcept; void reset() noexcept; template void reset(Y* p); template void reset(Y* p, D d); template void reset(Y* p, D d, A a); // observers: T* get() const noexcept; T& operator*() const noexcept; T* operator->() const noexcept; long use_count() const noexcept; bool unique() const noexcept; explicit operator bool() const noexcept; template bool owner_before(shared_ptr const& b) const noexcept; template bool owner_before(weak_ptr const& b) const noexcept; }; template shared_ptr(weak_ptr) -> shared_ptr; template shared_ptr(unique_ptr) -> shared_ptr; // shared_ptr comparisons: template bool operator==(shared_ptr const& a, shared_ptr const& b) noexcept; template bool operator!=(shared_ptr const& a, shared_ptr const& b) noexcept; template bool operator<(shared_ptr const& a, shared_ptr const& b) noexcept; template bool operator>(shared_ptr const& a, shared_ptr const& b) noexcept; template bool operator<=(shared_ptr const& a, shared_ptr const& b) noexcept; template bool operator>=(shared_ptr const& a, shared_ptr const& b) noexcept; template bool operator==(const shared_ptr& x, nullptr_t) noexcept; template bool operator==(nullptr_t, const shared_ptr& y) noexcept; template bool operator!=(const shared_ptr& x, nullptr_t) noexcept; template bool operator!=(nullptr_t, const shared_ptr& y) noexcept; template bool operator<(const shared_ptr& x, nullptr_t) noexcept; template bool operator<(nullptr_t, const shared_ptr& y) noexcept; template bool operator<=(const shared_ptr& x, nullptr_t) noexcept; template bool operator<=(nullptr_t, const shared_ptr& y) noexcept; template bool operator>(const shared_ptr& x, nullptr_t) noexcept; template bool operator>(nullptr_t, const shared_ptr& y) noexcept; template bool operator>=(const shared_ptr& x, nullptr_t) noexcept; template bool operator>=(nullptr_t, const shared_ptr& y) noexcept; // shared_ptr specialized algorithms: template void swap(shared_ptr& a, shared_ptr& b) noexcept; // shared_ptr casts: template shared_ptr static_pointer_cast(shared_ptr const& r) noexcept; template shared_ptr dynamic_pointer_cast(shared_ptr const& r) noexcept; template shared_ptr const_pointer_cast(shared_ptr const& r) noexcept; // shared_ptr I/O: template basic_ostream& operator<< (basic_ostream& os, shared_ptr const& p); // shared_ptr get_deleter: template D* get_deleter(shared_ptr const& p) noexcept; template shared_ptr make_shared(Args&&... args); template shared_ptr allocate_shared(const A& a, Args&&... args); template class weak_ptr { public: typedef T element_type; // constructors constexpr weak_ptr() noexcept; template weak_ptr(shared_ptr const& r) noexcept; weak_ptr(weak_ptr const& r) noexcept; template weak_ptr(weak_ptr const& r) noexcept; weak_ptr(weak_ptr&& r) noexcept; // C++14 template weak_ptr(weak_ptr&& r) noexcept; // C++14 // destructor ~weak_ptr(); // assignment weak_ptr& operator=(weak_ptr const& r) noexcept; template weak_ptr& operator=(weak_ptr const& r) noexcept; template weak_ptr& operator=(shared_ptr const& r) noexcept; weak_ptr& operator=(weak_ptr&& r) noexcept; // C++14 template weak_ptr& operator=(weak_ptr&& r) noexcept; // C++14 // modifiers void swap(weak_ptr& r) noexcept; void reset() noexcept; // observers long use_count() const noexcept; bool expired() const noexcept; shared_ptr lock() const noexcept; template bool owner_before(shared_ptr const& b) const noexcept; template bool owner_before(weak_ptr const& b) const noexcept; }; template weak_ptr(shared_ptr) -> weak_ptr; // weak_ptr specialized algorithms: template void swap(weak_ptr& a, weak_ptr& b) noexcept; // class owner_less: template struct owner_less; template struct owner_less > : binary_function, shared_ptr, bool> { typedef bool result_type; bool operator()(shared_ptr const&, shared_ptr const&) const noexcept; bool operator()(shared_ptr const&, weak_ptr const&) const noexcept; bool operator()(weak_ptr const&, shared_ptr const&) const noexcept; }; template struct owner_less > : binary_function, weak_ptr, bool> { typedef bool result_type; bool operator()(weak_ptr const&, weak_ptr const&) const noexcept; bool operator()(shared_ptr const&, weak_ptr const&) const noexcept; bool operator()(weak_ptr const&, shared_ptr const&) const noexcept; }; template <> // Added in C++14 struct owner_less { template bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept; template bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept; template bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept; template bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept; typedef void is_transparent; }; template class enable_shared_from_this { protected: constexpr enable_shared_from_this() noexcept; enable_shared_from_this(enable_shared_from_this const&) noexcept; enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept; ~enable_shared_from_this(); public: shared_ptr shared_from_this(); shared_ptr shared_from_this() const; }; template bool atomic_is_lock_free(const shared_ptr* p); template shared_ptr atomic_load(const shared_ptr* p); template shared_ptr atomic_load_explicit(const shared_ptr* p, memory_order mo); template void atomic_store(shared_ptr* p, shared_ptr r); template void atomic_store_explicit(shared_ptr* p, shared_ptr r, memory_order mo); template shared_ptr atomic_exchange(shared_ptr* p, shared_ptr r); template shared_ptr atomic_exchange_explicit(shared_ptr* p, shared_ptr r, memory_order mo); template bool atomic_compare_exchange_weak(shared_ptr* p, shared_ptr* v, shared_ptr w); template bool atomic_compare_exchange_strong( shared_ptr* p, shared_ptr* v, shared_ptr w); template bool atomic_compare_exchange_weak_explicit(shared_ptr* p, shared_ptr* v, shared_ptr w, memory_order success, memory_order failure); template bool atomic_compare_exchange_strong_explicit(shared_ptr* p, shared_ptr* v, shared_ptr w, memory_order success, memory_order failure); // Hash support template struct hash; template struct hash >; template struct hash >; template inline constexpr bool uses_allocator_v = uses_allocator::value; // Pointer safety enum class pointer_safety { relaxed, preferred, strict }; // since C++11 void declare_reachable(void *p); // since C++11 template T *undeclare_reachable(T *p); // since C++11 void declare_no_pointers(char *p, size_t n); // since C++11 void undeclare_no_pointers(char *p, size_t n); // since C++11 pointer_safety get_pointer_safety() noexcept; // since C++11 void* align(size_t alignment, size_t size, void*& ptr, size_t& space); } // std */ #include <__config> #include #include #include #include #include #include #include #include #include <__functional_base> #include #include #include #include #include <__memory/addressof.h> #include <__memory/allocation_guard.h> #include <__memory/allocator.h> #include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> #include <__memory/construct_at.h> #include <__memory/pointer_safety.h> #include <__memory/pointer_traits.h> #include <__memory/raw_storage_iterator.h> #include <__memory/shared_ptr.h> #include <__memory/temporary_buffer.h> #include <__memory/uninitialized_algorithms.h> #include <__memory/unique_ptr.h> #include #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) # include <__memory/auto_ptr.h> #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif _LIBCPP_PUSH_MACROS #include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_INLINE_VISIBILITY void __construct_forward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) { static_assert(__is_cpp17_move_insertable<_Alloc>::value, "The specified type does not meet the requirements of Cpp17MoveInsertable"); typedef allocator_traits<_Alloc> _Traits; for (; __begin1 != __end1; ++__begin1, (void)++__begin2) { _Traits::construct(__a, _VSTD::__to_address(__begin2), #ifdef _LIBCPP_NO_EXCEPTIONS _VSTD::move(*__begin1) #else _VSTD::move_if_noexcept(*__begin1) #endif ); } } template ::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) && is_trivially_move_constructible<_Tp>::value >::type> _LIBCPP_INLINE_VISIBILITY void __construct_forward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) { ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) { _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp)); __begin2 += _Np; } } template _LIBCPP_INLINE_VISIBILITY void __construct_range_forward(_Alloc& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2) { typedef allocator_traits<_Alloc> _Traits; for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) { _Traits::construct(__a, _VSTD::__to_address(__begin2), *__begin1); } } template ::type, class _RawDest = typename remove_const<_Dest>::type, class = typename enable_if< is_trivially_copy_constructible<_Dest>::value && is_same<_RawSource, _RawDest>::value && (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Dest*, _Source&>::value) >::type> _LIBCPP_INLINE_VISIBILITY void __construct_range_forward(_Alloc&, _Source* __begin1, _Source* __end1, _Dest*& __begin2) { ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) { _VSTD::memcpy(const_cast<_RawDest*>(__begin2), __begin1, _Np * sizeof(_Dest)); __begin2 += _Np; } } template _LIBCPP_INLINE_VISIBILITY void __construct_backward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) { static_assert(__is_cpp17_move_insertable<_Alloc>::value, "The specified type does not meet the requirements of Cpp17MoveInsertable"); typedef allocator_traits<_Alloc> _Traits; while (__end1 != __begin1) { _Traits::construct(__a, _VSTD::__to_address(__end2 - 1), #ifdef _LIBCPP_NO_EXCEPTIONS _VSTD::move(*--__end1) #else _VSTD::move_if_noexcept(*--__end1) #endif ); --__end2; } } template ::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) && is_trivially_move_constructible<_Tp>::value >::type> _LIBCPP_INLINE_VISIBILITY void __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) { ptrdiff_t _Np = __end1 - __begin1; __end2 -= _Np; if (_Np > 0) _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp)); } struct __destruct_n { private: size_t __size_; template _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();} template _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT {++__size_;} _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT {__size_ = __s;} _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT {} public: _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT : __size_(__s) {} template _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT {__incr(integral_constant::value>());} template _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT {__set(__s, integral_constant::value>());} template _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT {__process(__p, integral_constant::value>());} }; _LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space); // --- Helper for container swap -- template _LIBCPP_INLINE_VISIBILITY void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) #endif { using _VSTD::swap; swap(__a1, __a2); } template inline _LIBCPP_INLINE_VISIBILITY void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} template inline _LIBCPP_INLINE_VISIBILITY void __swap_allocator(_Alloc & __a1, _Alloc & __a2) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) #endif { _VSTD::__swap_allocator(__a1, __a2, integral_constant::propagate_on_container_swap::value>()); } template > struct __noexcept_move_assign_container : public integral_constant 14 || _Traits::is_always_equal::value #else && is_nothrow_move_assignable<_Alloc>::value #endif > {}; template struct __temp_value { typedef allocator_traits<_Alloc> _Traits; typename aligned_storage::type __v; _Alloc &__a; _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } _Tp & get() { return *__addr(); } template _LIBCPP_NO_CFI __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) { _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)), _VSTD::forward<_Args>(__args)...); } ~__temp_value() { _Traits::destroy(__a, __addr()); } }; template struct __is_allocator : false_type {}; template struct __is_allocator<_Alloc, typename __void_t::type, typename __void_t().allocate(size_t(0)))>::type > : true_type {}; // __builtin_new_allocator -- A non-templated helper for allocating and // deallocating memory using __builtin_operator_new and // __builtin_operator_delete. It should be used in preference to // `std::allocator` to avoid additional instantiations. struct __builtin_new_allocator { struct __builtin_new_deleter { typedef void* pointer_type; _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align) : __size_(__size), __align_(__align) {} void operator()(void* p) const _NOEXCEPT { _VSTD::__libcpp_deallocate(p, __size_, __align_); } private: size_t __size_; size_t __align_; }; typedef unique_ptr __holder_t; static __holder_t __allocate_bytes(size_t __s, size_t __align) { return __holder_t(_VSTD::__libcpp_allocate(__s, __align), __builtin_new_deleter(__s, __align)); } static void __deallocate_bytes(void* __p, size_t __s, size_t __align) _NOEXCEPT { _VSTD::__libcpp_deallocate(__p, __s, __align); } template _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE static __holder_t __allocate_type(size_t __n) { return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); } template _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT { __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); } }; _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 # include <__pstl_memory> #endif #endif // _LIBCPP_MEMORY