13e519524SHoward Hinnant// -*- C++ -*- 23e519524SHoward Hinnant//===-------------------------- memory ------------------------------------===// 33e519524SHoward Hinnant// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 73e519524SHoward Hinnant// 83e519524SHoward Hinnant//===----------------------------------------------------------------------===// 93e519524SHoward Hinnant 103e519524SHoward Hinnant#ifndef _LIBCPP_MEMORY 113e519524SHoward Hinnant#define _LIBCPP_MEMORY 123e519524SHoward Hinnant 133e519524SHoward Hinnant/* 143e519524SHoward Hinnant memory synopsis 153e519524SHoward Hinnant 163e519524SHoward Hinnantnamespace std 173e519524SHoward Hinnant{ 183e519524SHoward Hinnant 193e519524SHoward Hinnantstruct allocator_arg_t { }; 2040a01d53SMarshall Clowinline constexpr allocator_arg_t allocator_arg = allocator_arg_t(); 213e519524SHoward Hinnant 223e519524SHoward Hinnanttemplate <class T, class Alloc> struct uses_allocator; 233e519524SHoward Hinnant 243e519524SHoward Hinnanttemplate <class Ptr> 253e519524SHoward Hinnantstruct pointer_traits 263e519524SHoward Hinnant{ 273e519524SHoward Hinnant typedef Ptr pointer; 283e519524SHoward Hinnant typedef <details> element_type; 293e519524SHoward Hinnant typedef <details> difference_type; 303e519524SHoward Hinnant 313e519524SHoward Hinnant template <class U> using rebind = <details>; 323e519524SHoward Hinnant 333e519524SHoward Hinnant static pointer pointer_to(<details>); 343e519524SHoward Hinnant}; 353e519524SHoward Hinnant 363739fe79SHoward Hinnanttemplate <class T> 373739fe79SHoward Hinnantstruct pointer_traits<T*> 383739fe79SHoward Hinnant{ 393739fe79SHoward Hinnant typedef T* pointer; 403739fe79SHoward Hinnant typedef T element_type; 413739fe79SHoward Hinnant typedef ptrdiff_t difference_type; 423739fe79SHoward Hinnant 433739fe79SHoward Hinnant template <class U> using rebind = U*; 443739fe79SHoward Hinnant 4572720269SLouis Dionne static pointer pointer_to(<details>) noexcept; // constexpr in C++20 463739fe79SHoward Hinnant}; 473739fe79SHoward Hinnant 4832952747SEric Fiseliertemplate <class T> constexpr T* to_address(T* p) noexcept; // C++20 49f6326736SMarek Kurdejtemplate <class Ptr> constexpr auto to_address(const Ptr& p) noexcept; // C++20 5032952747SEric Fiselier 513e519524SHoward Hinnanttemplate <class Alloc> 523e519524SHoward Hinnantstruct allocator_traits 533e519524SHoward Hinnant{ 543e519524SHoward Hinnant typedef Alloc allocator_type; 553e519524SHoward Hinnant typedef typename allocator_type::value_type 563e519524SHoward Hinnant value_type; 573e519524SHoward Hinnant 583e519524SHoward Hinnant typedef Alloc::pointer | value_type* pointer; 593e519524SHoward Hinnant typedef Alloc::const_pointer 603e519524SHoward Hinnant | pointer_traits<pointer>::rebind<const value_type> 613e519524SHoward Hinnant const_pointer; 623e519524SHoward Hinnant typedef Alloc::void_pointer 633e519524SHoward Hinnant | pointer_traits<pointer>::rebind<void> 643e519524SHoward Hinnant void_pointer; 653e519524SHoward Hinnant typedef Alloc::const_void_pointer 663e519524SHoward Hinnant | pointer_traits<pointer>::rebind<const void> 673e519524SHoward Hinnant const_void_pointer; 683e519524SHoward Hinnant typedef Alloc::difference_type 69a4a1ef1fSHoward Hinnant | pointer_traits<pointer>::difference_type 70a4a1ef1fSHoward Hinnant difference_type; 71a4a1ef1fSHoward Hinnant typedef Alloc::size_type 72a4a1ef1fSHoward Hinnant | make_unsigned<difference_type>::type 73a4a1ef1fSHoward Hinnant size_type; 743e519524SHoward Hinnant typedef Alloc::propagate_on_container_copy_assignment 753e519524SHoward Hinnant | false_type propagate_on_container_copy_assignment; 763e519524SHoward Hinnant typedef Alloc::propagate_on_container_move_assignment 773e519524SHoward Hinnant | false_type propagate_on_container_move_assignment; 783e519524SHoward Hinnant typedef Alloc::propagate_on_container_swap 793e519524SHoward Hinnant | false_type propagate_on_container_swap; 8031a47313SMarshall Clow typedef Alloc::is_always_equal 8131a47313SMarshall Clow | is_empty is_always_equal; 823e519524SHoward Hinnant 835b1e5b43SMichael Park template <class T> using rebind_alloc = Alloc::rebind<T>::other | Alloc<T, Args...>; 843e519524SHoward Hinnant template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>; 853e519524SHoward Hinnant 860724f8bfSLouis Dionne static pointer allocate(allocator_type& a, size_type n); // constexpr and [[nodiscard]] in C++20 870724f8bfSLouis Dionne static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20 883e519524SHoward Hinnant 890724f8bfSLouis Dionne static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20 903e519524SHoward Hinnant 913e519524SHoward Hinnant template <class T, class... Args> 920724f8bfSLouis Dionne static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20 933e519524SHoward Hinnant 943e519524SHoward Hinnant template <class T> 950724f8bfSLouis Dionne static void destroy(allocator_type& a, T* p); // constexpr in C++20 963e519524SHoward Hinnant 970724f8bfSLouis Dionne static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20 980724f8bfSLouis Dionne static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20 993e519524SHoward Hinnant}; 1003e519524SHoward Hinnant 1013e519524SHoward Hinnanttemplate <> 1025b1e5b43SMichael Parkclass allocator<void> // deprecated in C++17, removed in C++20 1033e519524SHoward Hinnant{ 1043e519524SHoward Hinnantpublic: 1053e519524SHoward Hinnant typedef void* pointer; 1063e519524SHoward Hinnant typedef const void* const_pointer; 1073e519524SHoward Hinnant typedef void value_type; 1083e519524SHoward Hinnant 1093e519524SHoward Hinnant template <class _Up> struct rebind {typedef allocator<_Up> other;}; 1103e519524SHoward Hinnant}; 1113e519524SHoward Hinnant 1123e519524SHoward Hinnanttemplate <class T> 1133e519524SHoward Hinnantclass allocator 1143e519524SHoward Hinnant{ 1153e519524SHoward Hinnantpublic: 116316d336dSLouis Dionne typedef size_t size_type; 117316d336dSLouis Dionne typedef ptrdiff_t difference_type; 1185b1e5b43SMichael Park typedef T* pointer; // deprecated in C++17, removed in C++20 1195b1e5b43SMichael Park typedef const T* const_pointer; // deprecated in C++17, removed in C++20 1205b1e5b43SMichael Park typedef typename add_lvalue_reference<T>::type 1215b1e5b43SMichael Park reference; // deprecated in C++17, removed in C++20 1225b1e5b43SMichael Park typedef typename add_lvalue_reference<const T>::type 1235b1e5b43SMichael Park const_reference; // deprecated in C++17, removed in C++20 1245b1e5b43SMichael Park 1253e519524SHoward Hinnant typedef T value_type; 1263e519524SHoward Hinnant 1275b1e5b43SMichael Park template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20 1285b1e5b43SMichael Park 1295b1e5b43SMichael Park typedef true_type propagate_on_container_move_assignment; 1305b1e5b43SMichael Park typedef true_type is_always_equal; 1313e519524SHoward Hinnant 132e0742c4aSMarshall Clow constexpr allocator() noexcept; // constexpr in C++20 133e0742c4aSMarshall Clow constexpr allocator(const allocator&) noexcept; // constexpr in C++20 134e0742c4aSMarshall Clow template <class U> 135e0742c4aSMarshall Clow constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20 1360724f8bfSLouis Dionne ~allocator(); // constexpr in C++20 1375b1e5b43SMichael Park pointer address(reference x) const noexcept; // deprecated in C++17, removed in C++20 1385b1e5b43SMichael Park const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20 1395b1e5b43SMichael Park T* allocate(size_t n, const void* hint); // deprecated in C++17, removed in C++20 1400724f8bfSLouis Dionne T* allocate(size_t n); // constexpr in C++20 1410724f8bfSLouis Dionne void deallocate(T* p, size_t n) noexcept; // constexpr in C++20 1425b1e5b43SMichael Park size_type max_size() const noexcept; // deprecated in C++17, removed in C++20 1433739fe79SHoward Hinnant template<class U, class... Args> 1445b1e5b43SMichael Park void construct(U* p, Args&&... args); // deprecated in C++17, removed in C++20 1453739fe79SHoward Hinnant template <class U> 1465b1e5b43SMichael Park void destroy(U* p); // deprecated in C++17, removed in C++20 1473e519524SHoward Hinnant}; 1483e519524SHoward Hinnant 1493e519524SHoward Hinnanttemplate <class T, class U> 1500724f8bfSLouis Dionnebool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20 1513e519524SHoward Hinnant 1523e519524SHoward Hinnanttemplate <class T, class U> 1530724f8bfSLouis Dionnebool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20 1543e519524SHoward Hinnant 1553e519524SHoward Hinnanttemplate <class OutputIterator, class T> 1563e519524SHoward Hinnantclass raw_storage_iterator 1573e519524SHoward Hinnant : public iterator<output_iterator_tag, 1583e519524SHoward Hinnant T, // purposefully not C++03 1593e519524SHoward Hinnant ptrdiff_t, // purposefully not C++03 1603e519524SHoward Hinnant T*, // purposefully not C++03 1613e519524SHoward Hinnant raw_storage_iterator&> // purposefully not C++03 1623e519524SHoward Hinnant{ 1633e519524SHoward Hinnantpublic: 1643e519524SHoward Hinnant explicit raw_storage_iterator(OutputIterator x); 1653e519524SHoward Hinnant raw_storage_iterator& operator*(); 1663e519524SHoward Hinnant raw_storage_iterator& operator=(const T& element); 1673e519524SHoward Hinnant raw_storage_iterator& operator++(); 1683e519524SHoward Hinnant raw_storage_iterator operator++(int); 1693e519524SHoward Hinnant}; 1703e519524SHoward Hinnant 1713739fe79SHoward Hinnanttemplate <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept; 1723739fe79SHoward Hinnanttemplate <class T> void return_temporary_buffer(T* p) noexcept; 1733739fe79SHoward Hinnant 1743739fe79SHoward Hinnanttemplate <class T> T* addressof(T& r) noexcept; 1751c7fe126SMarshall Clowtemplate <class T> T* addressof(const T&& r) noexcept = delete; 1763e519524SHoward Hinnant 1773e519524SHoward Hinnanttemplate <class InputIterator, class ForwardIterator> 1783e519524SHoward HinnantForwardIterator 1793e519524SHoward Hinnantuninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); 1803e519524SHoward Hinnant 1813739fe79SHoward Hinnanttemplate <class InputIterator, class Size, class ForwardIterator> 1823739fe79SHoward HinnantForwardIterator 1833739fe79SHoward Hinnantuninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); 1843739fe79SHoward Hinnant 1853e519524SHoward Hinnanttemplate <class ForwardIterator, class T> 1863e519524SHoward Hinnantvoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); 1873e519524SHoward Hinnant 1883e519524SHoward Hinnanttemplate <class ForwardIterator, class Size, class T> 18948d05bd2SHoward HinnantForwardIterator 19048d05bd2SHoward Hinnantuninitialized_fill_n(ForwardIterator first, Size n, const T& x); 1913e519524SHoward Hinnant 1920724f8bfSLouis Dionnetemplate <class T, class ...Args> 1930724f8bfSLouis Dionneconstexpr T* construct_at(T* location, Args&& ...args); // since C++20 1940724f8bfSLouis Dionne 195e4d9c316SEric Fiseliertemplate <class T> 1960724f8bfSLouis Dionnevoid destroy_at(T* location); // constexpr in C++20 197e4d9c316SEric Fiselier 198e4d9c316SEric Fiseliertemplate <class ForwardIterator> 1990724f8bfSLouis Dionnevoid destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20 200e4d9c316SEric Fiselier 201e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size> 2020724f8bfSLouis DionneForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20 203e4d9c316SEric Fiselier 204e4d9c316SEric Fiseliertemplate <class InputIterator, class ForwardIterator> 205e4d9c316SEric Fiselier ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); 206e4d9c316SEric Fiselier 207e4d9c316SEric Fiseliertemplate <class InputIterator, class Size, class ForwardIterator> 208e4d9c316SEric Fiselier pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); 209e4d9c316SEric Fiselier 210e4d9c316SEric Fiseliertemplate <class ForwardIterator> 211e4d9c316SEric Fiselier void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); 212e4d9c316SEric Fiselier 213e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size> 214e4d9c316SEric Fiselier ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); 215e4d9c316SEric Fiselier 216e4d9c316SEric Fiseliertemplate <class ForwardIterator> 217e4d9c316SEric Fiselier void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); 218e4d9c316SEric Fiselier 219e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size> 220e4d9c316SEric Fiselier ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); 221e4d9c316SEric Fiselier 222ea5cd3b4SLouis Dionnetemplate <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17 2233e519524SHoward Hinnant 2243e519524SHoward Hinnanttemplate<class X> 225ea5cd3b4SLouis Dionneclass auto_ptr // deprecated in C++11, removed in C++17 2263e519524SHoward Hinnant{ 2273e519524SHoward Hinnantpublic: 2283e519524SHoward Hinnant typedef X element_type; 2293e519524SHoward Hinnant 2303e519524SHoward Hinnant explicit auto_ptr(X* p =0) throw(); 2313e519524SHoward Hinnant auto_ptr(auto_ptr&) throw(); 2323e519524SHoward Hinnant template<class Y> auto_ptr(auto_ptr<Y>&) throw(); 2333e519524SHoward Hinnant auto_ptr& operator=(auto_ptr&) throw(); 2343e519524SHoward Hinnant template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw(); 2353e519524SHoward Hinnant auto_ptr& operator=(auto_ptr_ref<X> r) throw(); 2363e519524SHoward Hinnant ~auto_ptr() throw(); 2373e519524SHoward Hinnant 2383e519524SHoward Hinnant typename add_lvalue_reference<X>::type operator*() const throw(); 2393e519524SHoward Hinnant X* operator->() const throw(); 2403e519524SHoward Hinnant X* get() const throw(); 2413e519524SHoward Hinnant X* release() throw(); 2423e519524SHoward Hinnant void reset(X* p =0) throw(); 2433e519524SHoward Hinnant 2443e519524SHoward Hinnant auto_ptr(auto_ptr_ref<X>) throw(); 2453e519524SHoward Hinnant template<class Y> operator auto_ptr_ref<Y>() throw(); 2463e519524SHoward Hinnant template<class Y> operator auto_ptr<Y>() throw(); 2473e519524SHoward Hinnant}; 2483e519524SHoward Hinnant 24920cc2a42SHoward Hinnanttemplate <class T> 25020cc2a42SHoward Hinnantstruct default_delete 25120cc2a42SHoward Hinnant{ 2523739fe79SHoward Hinnant constexpr default_delete() noexcept = default; 2533739fe79SHoward Hinnant template <class U> default_delete(const default_delete<U>&) noexcept; 25420cc2a42SHoward Hinnant 2553739fe79SHoward Hinnant void operator()(T*) const noexcept; 25620cc2a42SHoward Hinnant}; 25720cc2a42SHoward Hinnant 25820cc2a42SHoward Hinnanttemplate <class T> 25920cc2a42SHoward Hinnantstruct default_delete<T[]> 26020cc2a42SHoward Hinnant{ 2613739fe79SHoward Hinnant constexpr default_delete() noexcept = default; 2623739fe79SHoward Hinnant void operator()(T*) const noexcept; 26320cc2a42SHoward Hinnant template <class U> void operator()(U*) const = delete; 26420cc2a42SHoward Hinnant}; 26520cc2a42SHoward Hinnant 26620cc2a42SHoward Hinnanttemplate <class T, class D = default_delete<T>> 26720cc2a42SHoward Hinnantclass unique_ptr 26820cc2a42SHoward Hinnant{ 26920cc2a42SHoward Hinnantpublic: 27020cc2a42SHoward Hinnant typedef see below pointer; 27120cc2a42SHoward Hinnant typedef T element_type; 27220cc2a42SHoward Hinnant typedef D deleter_type; 27320cc2a42SHoward Hinnant 27420cc2a42SHoward Hinnant // constructors 2753739fe79SHoward Hinnant constexpr unique_ptr() noexcept; 2763739fe79SHoward Hinnant explicit unique_ptr(pointer p) noexcept; 2773739fe79SHoward Hinnant unique_ptr(pointer p, see below d1) noexcept; 2783739fe79SHoward Hinnant unique_ptr(pointer p, see below d2) noexcept; 2793739fe79SHoward Hinnant unique_ptr(unique_ptr&& u) noexcept; 2803739fe79SHoward Hinnant unique_ptr(nullptr_t) noexcept : unique_ptr() { } 28120cc2a42SHoward Hinnant template <class U, class E> 2823739fe79SHoward Hinnant unique_ptr(unique_ptr<U, E>&& u) noexcept; 28320cc2a42SHoward Hinnant template <class U> 284e67179bcSMarshall Clow unique_ptr(auto_ptr<U>&& u) noexcept; // removed in C++17 28520cc2a42SHoward Hinnant 28620cc2a42SHoward Hinnant // destructor 28720cc2a42SHoward Hinnant ~unique_ptr(); 28820cc2a42SHoward Hinnant 28920cc2a42SHoward Hinnant // assignment 2903739fe79SHoward Hinnant unique_ptr& operator=(unique_ptr&& u) noexcept; 2913739fe79SHoward Hinnant template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; 2923739fe79SHoward Hinnant unique_ptr& operator=(nullptr_t) noexcept; 29320cc2a42SHoward Hinnant 29420cc2a42SHoward Hinnant // observers 29520cc2a42SHoward Hinnant typename add_lvalue_reference<T>::type operator*() const; 2963739fe79SHoward Hinnant pointer operator->() const noexcept; 2973739fe79SHoward Hinnant pointer get() const noexcept; 2983739fe79SHoward Hinnant deleter_type& get_deleter() noexcept; 2993739fe79SHoward Hinnant const deleter_type& get_deleter() const noexcept; 3003739fe79SHoward Hinnant explicit operator bool() const noexcept; 30120cc2a42SHoward Hinnant 30220cc2a42SHoward Hinnant // modifiers 3033739fe79SHoward Hinnant pointer release() noexcept; 3043739fe79SHoward Hinnant void reset(pointer p = pointer()) noexcept; 3053739fe79SHoward Hinnant void swap(unique_ptr& u) noexcept; 30620cc2a42SHoward Hinnant}; 30720cc2a42SHoward Hinnant 30820cc2a42SHoward Hinnanttemplate <class T, class D> 30920cc2a42SHoward Hinnantclass unique_ptr<T[], D> 31020cc2a42SHoward Hinnant{ 31120cc2a42SHoward Hinnantpublic: 31220cc2a42SHoward Hinnant typedef implementation-defined pointer; 31320cc2a42SHoward Hinnant typedef T element_type; 31420cc2a42SHoward Hinnant typedef D deleter_type; 31520cc2a42SHoward Hinnant 31620cc2a42SHoward Hinnant // constructors 3173739fe79SHoward Hinnant constexpr unique_ptr() noexcept; 3183739fe79SHoward Hinnant explicit unique_ptr(pointer p) noexcept; 3193739fe79SHoward Hinnant unique_ptr(pointer p, see below d) noexcept; 3203739fe79SHoward Hinnant unique_ptr(pointer p, see below d) noexcept; 3213739fe79SHoward Hinnant unique_ptr(unique_ptr&& u) noexcept; 3223739fe79SHoward Hinnant unique_ptr(nullptr_t) noexcept : unique_ptr() { } 32320cc2a42SHoward Hinnant 32420cc2a42SHoward Hinnant // destructor 325b3371f6fSHoward Hinnant ~unique_ptr(); 32620cc2a42SHoward Hinnant 32720cc2a42SHoward Hinnant // assignment 3283739fe79SHoward Hinnant unique_ptr& operator=(unique_ptr&& u) noexcept; 3293739fe79SHoward Hinnant unique_ptr& operator=(nullptr_t) noexcept; 33020cc2a42SHoward Hinnant 33120cc2a42SHoward Hinnant // observers 33220cc2a42SHoward Hinnant T& operator[](size_t i) const; 3333739fe79SHoward Hinnant pointer get() const noexcept; 3343739fe79SHoward Hinnant deleter_type& get_deleter() noexcept; 3353739fe79SHoward Hinnant const deleter_type& get_deleter() const noexcept; 3363739fe79SHoward Hinnant explicit operator bool() const noexcept; 33720cc2a42SHoward Hinnant 33820cc2a42SHoward Hinnant // modifiers 3393739fe79SHoward Hinnant pointer release() noexcept; 3403739fe79SHoward Hinnant void reset(pointer p = pointer()) noexcept; 3413739fe79SHoward Hinnant void reset(nullptr_t) noexcept; 34220cc2a42SHoward Hinnant template <class U> void reset(U) = delete; 3433739fe79SHoward Hinnant void swap(unique_ptr& u) noexcept; 34420cc2a42SHoward Hinnant}; 34520cc2a42SHoward Hinnant 34620cc2a42SHoward Hinnanttemplate <class T, class D> 3473739fe79SHoward Hinnant void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; 34820cc2a42SHoward Hinnant 34920cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35020cc2a42SHoward Hinnant bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 35120cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35220cc2a42SHoward Hinnant bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 35320cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35420cc2a42SHoward Hinnant bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 35520cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35620cc2a42SHoward Hinnant bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 35720cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35820cc2a42SHoward Hinnant bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 35920cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 36020cc2a42SHoward Hinnant bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 36120cc2a42SHoward Hinnant 3623739fe79SHoward Hinnanttemplate <class T, class D> 3633739fe79SHoward Hinnant bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; 3643739fe79SHoward Hinnanttemplate <class T, class D> 3653739fe79SHoward Hinnant bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; 3663739fe79SHoward Hinnanttemplate <class T, class D> 3673739fe79SHoward Hinnant bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; 3683739fe79SHoward Hinnanttemplate <class T, class D> 3693739fe79SHoward Hinnant bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; 3703739fe79SHoward Hinnant 3713739fe79SHoward Hinnanttemplate <class T, class D> 3723739fe79SHoward Hinnant bool operator<(const unique_ptr<T, D>& x, nullptr_t); 3733739fe79SHoward Hinnanttemplate <class T, class D> 3743739fe79SHoward Hinnant bool operator<(nullptr_t, const unique_ptr<T, D>& y); 3753739fe79SHoward Hinnanttemplate <class T, class D> 3763739fe79SHoward Hinnant bool operator<=(const unique_ptr<T, D>& x, nullptr_t); 3773739fe79SHoward Hinnanttemplate <class T, class D> 3783739fe79SHoward Hinnant bool operator<=(nullptr_t, const unique_ptr<T, D>& y); 3793739fe79SHoward Hinnanttemplate <class T, class D> 3803739fe79SHoward Hinnant bool operator>(const unique_ptr<T, D>& x, nullptr_t); 3813739fe79SHoward Hinnanttemplate <class T, class D> 3823739fe79SHoward Hinnant bool operator>(nullptr_t, const unique_ptr<T, D>& y); 3833739fe79SHoward Hinnanttemplate <class T, class D> 3843739fe79SHoward Hinnant bool operator>=(const unique_ptr<T, D>& x, nullptr_t); 3853739fe79SHoward Hinnanttemplate <class T, class D> 3863739fe79SHoward Hinnant bool operator>=(nullptr_t, const unique_ptr<T, D>& y); 3873739fe79SHoward Hinnant 38820cc2a42SHoward Hinnantclass bad_weak_ptr 38920cc2a42SHoward Hinnant : public std::exception 39020cc2a42SHoward Hinnant{ 3913739fe79SHoward Hinnant bad_weak_ptr() noexcept; 39220cc2a42SHoward Hinnant}; 39320cc2a42SHoward Hinnant 39428d8ba5fSMarshall Clowtemplate<class T, class... Args> unique_ptr<T> make_unique(Args&&... args); // C++14 39528d8ba5fSMarshall Clowtemplate<class T> unique_ptr<T> make_unique(size_t n); // C++14 39628d8ba5fSMarshall Clowtemplate<class T, class... Args> unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] 39728d8ba5fSMarshall Clow 39848f36539SMarshall Clowtemplate<class E, class T, class Y, class D> 39948f36539SMarshall Clow basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p); 40048f36539SMarshall Clow 40120cc2a42SHoward Hinnanttemplate<class T> 40220cc2a42SHoward Hinnantclass shared_ptr 40320cc2a42SHoward Hinnant{ 40420cc2a42SHoward Hinnantpublic: 40520cc2a42SHoward Hinnant typedef T element_type; 40668436a9bSEric Fiselier typedef weak_ptr<T> weak_type; // C++17 40720cc2a42SHoward Hinnant 40820cc2a42SHoward Hinnant // constructors: 4093739fe79SHoward Hinnant constexpr shared_ptr() noexcept; 41020cc2a42SHoward Hinnant template<class Y> explicit shared_ptr(Y* p); 41120cc2a42SHoward Hinnant template<class Y, class D> shared_ptr(Y* p, D d); 41220cc2a42SHoward Hinnant template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); 41320cc2a42SHoward Hinnant template <class D> shared_ptr(nullptr_t p, D d); 41420cc2a42SHoward Hinnant template <class D, class A> shared_ptr(nullptr_t p, D d, A a); 4153739fe79SHoward Hinnant template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept; 4163739fe79SHoward Hinnant shared_ptr(const shared_ptr& r) noexcept; 4173739fe79SHoward Hinnant template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept; 4183739fe79SHoward Hinnant shared_ptr(shared_ptr&& r) noexcept; 4193739fe79SHoward Hinnant template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept; 42020cc2a42SHoward Hinnant template<class Y> explicit shared_ptr(const weak_ptr<Y>& r); 421e67179bcSMarshall Clow template<class Y> shared_ptr(auto_ptr<Y>&& r); // removed in C++17 42220cc2a42SHoward Hinnant template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r); 42320cc2a42SHoward Hinnant shared_ptr(nullptr_t) : shared_ptr() { } 42420cc2a42SHoward Hinnant 42520cc2a42SHoward Hinnant // destructor: 42620cc2a42SHoward Hinnant ~shared_ptr(); 42720cc2a42SHoward Hinnant 42820cc2a42SHoward Hinnant // assignment: 4293739fe79SHoward Hinnant shared_ptr& operator=(const shared_ptr& r) noexcept; 4303739fe79SHoward Hinnant template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept; 4313739fe79SHoward Hinnant shared_ptr& operator=(shared_ptr&& r) noexcept; 43220cc2a42SHoward Hinnant template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r); 433e67179bcSMarshall Clow template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17 43420cc2a42SHoward Hinnant template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r); 43520cc2a42SHoward Hinnant 43620cc2a42SHoward Hinnant // modifiers: 4373739fe79SHoward Hinnant void swap(shared_ptr& r) noexcept; 4383739fe79SHoward Hinnant void reset() noexcept; 43920cc2a42SHoward Hinnant template<class Y> void reset(Y* p); 44020cc2a42SHoward Hinnant template<class Y, class D> void reset(Y* p, D d); 44120cc2a42SHoward Hinnant template<class Y, class D, class A> void reset(Y* p, D d, A a); 44220cc2a42SHoward Hinnant 4433739fe79SHoward Hinnant // observers: 4443739fe79SHoward Hinnant T* get() const noexcept; 4453739fe79SHoward Hinnant T& operator*() const noexcept; 4463739fe79SHoward Hinnant T* operator->() const noexcept; 4473739fe79SHoward Hinnant long use_count() const noexcept; 4483739fe79SHoward Hinnant bool unique() const noexcept; 4493739fe79SHoward Hinnant explicit operator bool() const noexcept; 45036bc7178SMarshall Clow template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept; 45136bc7178SMarshall Clow template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept; 45220cc2a42SHoward Hinnant}; 45320cc2a42SHoward Hinnant 45483564056SLogan Smithtemplate<class T> 45583564056SLogan Smithshared_ptr(weak_ptr<T>) -> shared_ptr<T>; 45683564056SLogan Smithtemplate<class T, class D> 45783564056SLogan Smithshared_ptr(unique_ptr<T, D>) -> shared_ptr<T>; 45883564056SLogan Smith 45920cc2a42SHoward Hinnant// shared_ptr comparisons: 46020cc2a42SHoward Hinnanttemplate<class T, class U> 4613739fe79SHoward Hinnant bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 46220cc2a42SHoward Hinnanttemplate<class T, class U> 4633739fe79SHoward Hinnant bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 46420cc2a42SHoward Hinnanttemplate<class T, class U> 4653739fe79SHoward Hinnant bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 46620cc2a42SHoward Hinnanttemplate<class T, class U> 4673739fe79SHoward Hinnant bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 46820cc2a42SHoward Hinnanttemplate<class T, class U> 4693739fe79SHoward Hinnant bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 47020cc2a42SHoward Hinnanttemplate<class T, class U> 4713739fe79SHoward Hinnant bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 4723739fe79SHoward Hinnant 4733739fe79SHoward Hinnanttemplate <class T> 4743739fe79SHoward Hinnant bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept; 4753739fe79SHoward Hinnanttemplate <class T> 4763739fe79SHoward Hinnant bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept; 4773739fe79SHoward Hinnanttemplate <class T> 4783739fe79SHoward Hinnant bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept; 4793739fe79SHoward Hinnanttemplate <class T> 4803739fe79SHoward Hinnant bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept; 4813739fe79SHoward Hinnanttemplate <class T> 4823739fe79SHoward Hinnant bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept; 4833739fe79SHoward Hinnanttemplate <class T> 4843739fe79SHoward Hinnantbool operator<(nullptr_t, const shared_ptr<T>& y) noexcept; 4853739fe79SHoward Hinnanttemplate <class T> 4863739fe79SHoward Hinnant bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept; 4873739fe79SHoward Hinnanttemplate <class T> 4883739fe79SHoward Hinnant bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept; 4893739fe79SHoward Hinnanttemplate <class T> 4903739fe79SHoward Hinnant bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept; 4913739fe79SHoward Hinnanttemplate <class T> 4923739fe79SHoward Hinnant bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept; 4933739fe79SHoward Hinnanttemplate <class T> 4943739fe79SHoward Hinnant bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept; 4953739fe79SHoward Hinnanttemplate <class T> 4963739fe79SHoward Hinnant bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept; 49720cc2a42SHoward Hinnant 49820cc2a42SHoward Hinnant// shared_ptr specialized algorithms: 4993739fe79SHoward Hinnanttemplate<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept; 50020cc2a42SHoward Hinnant 50120cc2a42SHoward Hinnant// shared_ptr casts: 50220cc2a42SHoward Hinnanttemplate<class T, class U> 5033739fe79SHoward Hinnant shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept; 50420cc2a42SHoward Hinnanttemplate<class T, class U> 5053739fe79SHoward Hinnant shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept; 50620cc2a42SHoward Hinnanttemplate<class T, class U> 5073739fe79SHoward Hinnant shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept; 50820cc2a42SHoward Hinnant 50920cc2a42SHoward Hinnant// shared_ptr I/O: 51020cc2a42SHoward Hinnanttemplate<class E, class T, class Y> 51120cc2a42SHoward Hinnant basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p); 51220cc2a42SHoward Hinnant 51320cc2a42SHoward Hinnant// shared_ptr get_deleter: 5143739fe79SHoward Hinnanttemplate<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept; 51520cc2a42SHoward Hinnant 51620cc2a42SHoward Hinnanttemplate<class T, class... Args> 51720cc2a42SHoward Hinnant shared_ptr<T> make_shared(Args&&... args); 51820cc2a42SHoward Hinnanttemplate<class T, class A, class... Args> 51920cc2a42SHoward Hinnant shared_ptr<T> allocate_shared(const A& a, Args&&... args); 52020cc2a42SHoward Hinnant 52120cc2a42SHoward Hinnanttemplate<class T> 52220cc2a42SHoward Hinnantclass weak_ptr 52320cc2a42SHoward Hinnant{ 52420cc2a42SHoward Hinnantpublic: 52520cc2a42SHoward Hinnant typedef T element_type; 52620cc2a42SHoward Hinnant 52720cc2a42SHoward Hinnant // constructors 5283739fe79SHoward Hinnant constexpr weak_ptr() noexcept; 5293739fe79SHoward Hinnant template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept; 5303739fe79SHoward Hinnant weak_ptr(weak_ptr const& r) noexcept; 5313739fe79SHoward Hinnant template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept; 5324703f763SMarshall Clow weak_ptr(weak_ptr&& r) noexcept; // C++14 5334703f763SMarshall Clow template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14 53420cc2a42SHoward Hinnant 53520cc2a42SHoward Hinnant // destructor 53620cc2a42SHoward Hinnant ~weak_ptr(); 53720cc2a42SHoward Hinnant 53820cc2a42SHoward Hinnant // assignment 5393739fe79SHoward Hinnant weak_ptr& operator=(weak_ptr const& r) noexcept; 5403739fe79SHoward Hinnant template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept; 5413739fe79SHoward Hinnant template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept; 5424703f763SMarshall Clow weak_ptr& operator=(weak_ptr&& r) noexcept; // C++14 5434703f763SMarshall Clow template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14 54420cc2a42SHoward Hinnant 54520cc2a42SHoward Hinnant // modifiers 5463739fe79SHoward Hinnant void swap(weak_ptr& r) noexcept; 5473739fe79SHoward Hinnant void reset() noexcept; 54820cc2a42SHoward Hinnant 54920cc2a42SHoward Hinnant // observers 5503739fe79SHoward Hinnant long use_count() const noexcept; 5513739fe79SHoward Hinnant bool expired() const noexcept; 5523739fe79SHoward Hinnant shared_ptr<T> lock() const noexcept; 55336bc7178SMarshall Clow template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept; 55436bc7178SMarshall Clow template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept; 55520cc2a42SHoward Hinnant}; 55620cc2a42SHoward Hinnant 55783564056SLogan Smithtemplate<class T> 55883564056SLogan Smithweak_ptr(shared_ptr<T>) -> weak_ptr<T>; 55983564056SLogan Smith 56020cc2a42SHoward Hinnant// weak_ptr specialized algorithms: 5613739fe79SHoward Hinnanttemplate<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; 56220cc2a42SHoward Hinnant 56320cc2a42SHoward Hinnant// class owner_less: 56420cc2a42SHoward Hinnanttemplate<class T> struct owner_less; 56520cc2a42SHoward Hinnant 56620cc2a42SHoward Hinnanttemplate<class T> 56720cc2a42SHoward Hinnantstruct owner_less<shared_ptr<T> > 56820cc2a42SHoward Hinnant : binary_function<shared_ptr<T>, shared_ptr<T>, bool> 56920cc2a42SHoward Hinnant{ 57020cc2a42SHoward Hinnant typedef bool result_type; 57136bc7178SMarshall Clow bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept; 57236bc7178SMarshall Clow bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept; 57336bc7178SMarshall Clow bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept; 57420cc2a42SHoward Hinnant}; 57520cc2a42SHoward Hinnant 57620cc2a42SHoward Hinnanttemplate<class T> 57720cc2a42SHoward Hinnantstruct owner_less<weak_ptr<T> > 57820cc2a42SHoward Hinnant : binary_function<weak_ptr<T>, weak_ptr<T>, bool> 57920cc2a42SHoward Hinnant{ 58020cc2a42SHoward Hinnant typedef bool result_type; 58136bc7178SMarshall Clow bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept; 58236bc7178SMarshall Clow bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept; 58336bc7178SMarshall Clow bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept; 58436bc7178SMarshall Clow}; 58536bc7178SMarshall Clow 58636bc7178SMarshall Clowtemplate <> // Added in C++14 58736bc7178SMarshall Clowstruct owner_less<void> 58836bc7178SMarshall Clow{ 58936bc7178SMarshall Clow template <class _Tp, class _Up> 59036bc7178SMarshall Clow bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept; 59136bc7178SMarshall Clow template <class _Tp, class _Up> 59236bc7178SMarshall Clow bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept; 59336bc7178SMarshall Clow template <class _Tp, class _Up> 59436bc7178SMarshall Clow bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept; 59536bc7178SMarshall Clow template <class _Tp, class _Up> 59636bc7178SMarshall Clow bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept; 59736bc7178SMarshall Clow 59836bc7178SMarshall Clow typedef void is_transparent; 59920cc2a42SHoward Hinnant}; 60020cc2a42SHoward Hinnant 60120cc2a42SHoward Hinnanttemplate<class T> 60220cc2a42SHoward Hinnantclass enable_shared_from_this 60320cc2a42SHoward Hinnant{ 60420cc2a42SHoward Hinnantprotected: 6053739fe79SHoward Hinnant constexpr enable_shared_from_this() noexcept; 6063739fe79SHoward Hinnant enable_shared_from_this(enable_shared_from_this const&) noexcept; 6073739fe79SHoward Hinnant enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept; 60820cc2a42SHoward Hinnant ~enable_shared_from_this(); 60920cc2a42SHoward Hinnantpublic: 61020cc2a42SHoward Hinnant shared_ptr<T> shared_from_this(); 61120cc2a42SHoward Hinnant shared_ptr<T const> shared_from_this() const; 61220cc2a42SHoward Hinnant}; 61320cc2a42SHoward Hinnant 61420cc2a42SHoward Hinnanttemplate<class T> 61520cc2a42SHoward Hinnant bool atomic_is_lock_free(const shared_ptr<T>* p); 61620cc2a42SHoward Hinnanttemplate<class T> 61720cc2a42SHoward Hinnant shared_ptr<T> atomic_load(const shared_ptr<T>* p); 61820cc2a42SHoward Hinnanttemplate<class T> 61920cc2a42SHoward Hinnant shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo); 62020cc2a42SHoward Hinnanttemplate<class T> 62120cc2a42SHoward Hinnant void atomic_store(shared_ptr<T>* p, shared_ptr<T> r); 62220cc2a42SHoward Hinnanttemplate<class T> 62320cc2a42SHoward Hinnant void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); 62420cc2a42SHoward Hinnanttemplate<class T> 62520cc2a42SHoward Hinnant shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r); 62620cc2a42SHoward Hinnanttemplate<class T> 62720cc2a42SHoward Hinnant shared_ptr<T> 62820cc2a42SHoward Hinnant atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); 62920cc2a42SHoward Hinnanttemplate<class T> 63020cc2a42SHoward Hinnant bool 63120cc2a42SHoward Hinnant atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); 63220cc2a42SHoward Hinnanttemplate<class T> 63320cc2a42SHoward Hinnant bool 63420cc2a42SHoward Hinnant atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); 63520cc2a42SHoward Hinnanttemplate<class T> 63620cc2a42SHoward Hinnant bool 63720cc2a42SHoward Hinnant atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v, 63820cc2a42SHoward Hinnant shared_ptr<T> w, memory_order success, 63920cc2a42SHoward Hinnant memory_order failure); 64020cc2a42SHoward Hinnanttemplate<class T> 64120cc2a42SHoward Hinnant bool 64220cc2a42SHoward Hinnant atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v, 64320cc2a42SHoward Hinnant shared_ptr<T> w, memory_order success, 64420cc2a42SHoward Hinnant memory_order failure); 64520cc2a42SHoward Hinnant// Hash support 64620cc2a42SHoward Hinnanttemplate <class T> struct hash; 64720cc2a42SHoward Hinnanttemplate <class T, class D> struct hash<unique_ptr<T, D> >; 64820cc2a42SHoward Hinnanttemplate <class T> struct hash<shared_ptr<T> >; 64920cc2a42SHoward Hinnant 65040a01d53SMarshall Clowtemplate <class T, class Alloc> 65140a01d53SMarshall Clow inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value; 65240a01d53SMarshall Clow 65320cc2a42SHoward Hinnant// Pointer safety 654*49e7be2eSLouis Dionneenum class pointer_safety { relaxed, preferred, strict }; // since C++11 655*49e7be2eSLouis Dionnevoid declare_reachable(void *p); // since C++11 656*49e7be2eSLouis Dionnetemplate <class T> T *undeclare_reachable(T *p); // since C++11 657*49e7be2eSLouis Dionnevoid declare_no_pointers(char *p, size_t n); // since C++11 658*49e7be2eSLouis Dionnevoid undeclare_no_pointers(char *p, size_t n); // since C++11 659*49e7be2eSLouis Dionnepointer_safety get_pointer_safety() noexcept; // since C++11 66020cc2a42SHoward Hinnant 6613e519524SHoward Hinnantvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space); 6623e519524SHoward Hinnant 6633e519524SHoward Hinnant} // std 6643e519524SHoward Hinnant 6653e519524SHoward Hinnant*/ 6663e519524SHoward Hinnant 6673e519524SHoward Hinnant#include <__config> 6683e519524SHoward Hinnant#include <type_traits> 6693e519524SHoward Hinnant#include <typeinfo> 6702d0f1fa4SArthur O'Dwyer#include <compare> 6713e519524SHoward Hinnant#include <cstddef> 6723e519524SHoward Hinnant#include <cstdint> 6733e519524SHoward Hinnant#include <new> 6743e519524SHoward Hinnant#include <utility> 6753e519524SHoward Hinnant#include <iterator> 6763e519524SHoward Hinnant#include <__functional_base> 677e3163f5aSHoward Hinnant#include <iosfwd> 678a87b5e34SHoward Hinnant#include <tuple> 6794524d6e7SEric Fiselier#include <stdexcept> 6809741d6c9SHoward Hinnant#include <cstring> 681f992cfbaSLouis Dionne#include <__memory/addressof.h> 682e98060faSLouis Dionne#include <__memory/allocation_guard.h> 6830b439e4cSLouis Dionne#include <__memory/allocator.h> 6847ad49aecSLouis Dionne#include <__memory/allocator_traits.h> 6859b0a3388SLouis Dionne#include <__memory/compressed_pair.h> 686f992cfbaSLouis Dionne#include <__memory/construct_at.h> 6877f1963dcSLouis Dionne#include <__memory/pointer_safety.h> 6887ad49aecSLouis Dionne#include <__memory/pointer_traits.h> 689be54341cSLouis Dionne#include <__memory/raw_storage_iterator.h> 690916fecb4SLouis Dionne#include <__memory/shared_ptr.h> 6916a1ac88fSLouis Dionne#include <__memory/temporary_buffer.h> 6924f9b2469SLouis Dionne#include <__memory/uninitialized_algorithms.h> 69321d6636dSLouis Dionne#include <__memory/unique_ptr.h> 694f56972e2SMarshall Clow#include <version> 695d77851e8SHoward Hinnant 696207d58bfSLouis Dionne#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 697207d58bfSLouis Dionne# include <__memory/auto_ptr.h> 698207d58bfSLouis Dionne#endif 699207d58bfSLouis Dionne 700073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 7013e519524SHoward Hinnant#pragma GCC system_header 702073458b1SHoward Hinnant#endif 7033e519524SHoward Hinnant 704a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS 705a016efb1SEric Fiselier#include <__undef_macros> 706a016efb1SEric Fiselier 707a016efb1SEric Fiselier 7083e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 7093e519524SHoward Hinnant 710d9a4f936SLouis Dionnetemplate <class _Alloc, class _Ptr> 711d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 712d9a4f936SLouis Dionnevoid __construct_forward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) { 713d9a4f936SLouis Dionne static_assert(__is_cpp17_move_insertable<_Alloc>::value, 714e9eb9999SArthur O'Dwyer "The specified type does not meet the requirements of Cpp17MoveInsertable"); 715d9a4f936SLouis Dionne typedef allocator_traits<_Alloc> _Traits; 716d9a4f936SLouis Dionne for (; __begin1 != __end1; ++__begin1, (void)++__begin2) { 717d9a4f936SLouis Dionne _Traits::construct(__a, _VSTD::__to_address(__begin2), 718d9a4f936SLouis Dionne#ifdef _LIBCPP_NO_EXCEPTIONS 719d9a4f936SLouis Dionne _VSTD::move(*__begin1) 720d9a4f936SLouis Dionne#else 721d9a4f936SLouis Dionne _VSTD::move_if_noexcept(*__begin1) 722d9a4f936SLouis Dionne#endif 723d9a4f936SLouis Dionne ); 724d9a4f936SLouis Dionne } 725d9a4f936SLouis Dionne} 726d9a4f936SLouis Dionne 727d9a4f936SLouis Dionnetemplate <class _Alloc, class _Tp, typename enable_if< 728d9a4f936SLouis Dionne (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) && 729d9a4f936SLouis Dionne is_trivially_move_constructible<_Tp>::value 730d9a4f936SLouis Dionne>::type> 731d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 732d9a4f936SLouis Dionnevoid __construct_forward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) { 733d9a4f936SLouis Dionne ptrdiff_t _Np = __end1 - __begin1; 734d9a4f936SLouis Dionne if (_Np > 0) { 735d9a4f936SLouis Dionne _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp)); 736d9a4f936SLouis Dionne __begin2 += _Np; 737d9a4f936SLouis Dionne } 738d9a4f936SLouis Dionne} 739d9a4f936SLouis Dionne 740d9a4f936SLouis Dionnetemplate <class _Alloc, class _Iter, class _Ptr> 741d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 742d9a4f936SLouis Dionnevoid __construct_range_forward(_Alloc& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2) { 743d9a4f936SLouis Dionne typedef allocator_traits<_Alloc> _Traits; 744d9a4f936SLouis Dionne for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) { 745d9a4f936SLouis Dionne _Traits::construct(__a, _VSTD::__to_address(__begin2), *__begin1); 746d9a4f936SLouis Dionne } 747d9a4f936SLouis Dionne} 748d9a4f936SLouis Dionne 749d9a4f936SLouis Dionnetemplate <class _Alloc, class _Source, class _Dest, 750d9a4f936SLouis Dionne class _RawSource = typename remove_const<_Source>::type, 751d9a4f936SLouis Dionne class _RawDest = typename remove_const<_Dest>::type, 752d9a4f936SLouis Dionne class = 753d9a4f936SLouis Dionne typename enable_if< 754d9a4f936SLouis Dionne is_trivially_copy_constructible<_Dest>::value && 755d9a4f936SLouis Dionne is_same<_RawSource, _RawDest>::value && 756d9a4f936SLouis Dionne (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Dest*, _Source&>::value) 757d9a4f936SLouis Dionne >::type> 758d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 759d9a4f936SLouis Dionnevoid __construct_range_forward(_Alloc&, _Source* __begin1, _Source* __end1, _Dest*& __begin2) { 760d9a4f936SLouis Dionne ptrdiff_t _Np = __end1 - __begin1; 761d9a4f936SLouis Dionne if (_Np > 0) { 762d9a4f936SLouis Dionne _VSTD::memcpy(const_cast<_RawDest*>(__begin2), __begin1, _Np * sizeof(_Dest)); 763d9a4f936SLouis Dionne __begin2 += _Np; 764d9a4f936SLouis Dionne } 765d9a4f936SLouis Dionne} 766d9a4f936SLouis Dionne 767d9a4f936SLouis Dionnetemplate <class _Alloc, class _Ptr> 768d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 769d9a4f936SLouis Dionnevoid __construct_backward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) { 770d9a4f936SLouis Dionne static_assert(__is_cpp17_move_insertable<_Alloc>::value, 771d9a4f936SLouis Dionne "The specified type does not meet the requirements of Cpp17MoveInsertable"); 772d9a4f936SLouis Dionne typedef allocator_traits<_Alloc> _Traits; 773d9a4f936SLouis Dionne while (__end1 != __begin1) { 774d9a4f936SLouis Dionne _Traits::construct(__a, _VSTD::__to_address(__end2 - 1), 775d9a4f936SLouis Dionne#ifdef _LIBCPP_NO_EXCEPTIONS 776d9a4f936SLouis Dionne _VSTD::move(*--__end1) 777d9a4f936SLouis Dionne#else 778d9a4f936SLouis Dionne _VSTD::move_if_noexcept(*--__end1) 779d9a4f936SLouis Dionne#endif 780d9a4f936SLouis Dionne ); 781d9a4f936SLouis Dionne --__end2; 782d9a4f936SLouis Dionne } 783d9a4f936SLouis Dionne} 784d9a4f936SLouis Dionne 785d9a4f936SLouis Dionnetemplate <class _Alloc, class _Tp, class = typename enable_if< 786d9a4f936SLouis Dionne (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) && 787d9a4f936SLouis Dionne is_trivially_move_constructible<_Tp>::value 788d9a4f936SLouis Dionne>::type> 789d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 790d9a4f936SLouis Dionnevoid __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) { 791d9a4f936SLouis Dionne ptrdiff_t _Np = __end1 - __begin1; 792d9a4f936SLouis Dionne __end2 -= _Np; 793d9a4f936SLouis Dionne if (_Np > 0) 794d9a4f936SLouis Dionne _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp)); 795d9a4f936SLouis Dionne} 796d9a4f936SLouis Dionne 7973e519524SHoward Hinnantstruct __destruct_n 7983e519524SHoward Hinnant{ 7993e519524SHoward Hinnantprivate: 8009ffacf3dSEric Fiselier size_t __size_; 8013e519524SHoward Hinnant 8023e519524SHoward Hinnant template <class _Tp> 8033739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT 8049ffacf3dSEric Fiselier {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();} 8053e519524SHoward Hinnant 8063e519524SHoward Hinnant template <class _Tp> 8073739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT 8083e519524SHoward Hinnant {} 8093e519524SHoward Hinnant 8103739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT 8119ffacf3dSEric Fiselier {++__size_;} 8123739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT 8133e519524SHoward Hinnant {} 8143e519524SHoward Hinnant 8153739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT 8169ffacf3dSEric Fiselier {__size_ = __s;} 8173739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT 8183e519524SHoward Hinnant {} 8193e519524SHoward Hinnantpublic: 8203739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT 8219ffacf3dSEric Fiselier : __size_(__s) {} 8223e519524SHoward Hinnant 8233e519524SHoward Hinnant template <class _Tp> 824527a7fdfSBruce Mitchener _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT 825ca740483SHoward Hinnant {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 8263e519524SHoward Hinnant 8273e519524SHoward Hinnant template <class _Tp> 8283739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT 829ca740483SHoward Hinnant {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 8303e519524SHoward Hinnant 8313e519524SHoward Hinnant template <class _Tp> 8323739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT 833ca740483SHoward Hinnant {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 8343e519524SHoward Hinnant}; 8353e519524SHoward Hinnant 836f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space); 8373e519524SHoward Hinnant 838e3fbe143SMarshall Clow// --- Helper for container swap -- 839e3fbe143SMarshall Clowtemplate <typename _Alloc> 840e3fbe143SMarshall Clow_LIBCPP_INLINE_VISIBILITY 841e3fbe143SMarshall Clowvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) 842e3fbe143SMarshall Clow#if _LIBCPP_STD_VER >= 14 843e3fbe143SMarshall Clow _NOEXCEPT 844e3fbe143SMarshall Clow#else 845e3fbe143SMarshall Clow _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) 846e3fbe143SMarshall Clow#endif 847e3fbe143SMarshall Clow{ 848e3fbe143SMarshall Clow using _VSTD::swap; 849e3fbe143SMarshall Clow swap(__a1, __a2); 850e3fbe143SMarshall Clow} 851e3fbe143SMarshall Clow 852e3fbe143SMarshall Clowtemplate <typename _Alloc> 85389dd1dd2SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 854e3fbe143SMarshall Clowvoid __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} 855e3fbe143SMarshall Clow 8566e965df6SArthur O'Dwyertemplate <typename _Alloc> 8576e965df6SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY 8586e965df6SArthur O'Dwyervoid __swap_allocator(_Alloc & __a1, _Alloc & __a2) 8596e965df6SArthur O'Dwyer#if _LIBCPP_STD_VER >= 14 8606e965df6SArthur O'Dwyer _NOEXCEPT 8616e965df6SArthur O'Dwyer#else 8626e965df6SArthur O'Dwyer _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) 8636e965df6SArthur O'Dwyer#endif 8646e965df6SArthur O'Dwyer{ 8656e965df6SArthur O'Dwyer _VSTD::__swap_allocator(__a1, __a2, 8666e965df6SArthur O'Dwyer integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>()); 8676e965df6SArthur O'Dwyer} 8686e965df6SArthur O'Dwyer 8691378a5aeSMarshall Clowtemplate <typename _Alloc, typename _Traits=allocator_traits<_Alloc> > 8701378a5aeSMarshall Clowstruct __noexcept_move_assign_container : public integral_constant<bool, 8711378a5aeSMarshall Clow _Traits::propagate_on_container_move_assignment::value 8721378a5aeSMarshall Clow#if _LIBCPP_STD_VER > 14 8731378a5aeSMarshall Clow || _Traits::is_always_equal::value 8741378a5aeSMarshall Clow#else 8751378a5aeSMarshall Clow && is_nothrow_move_assignable<_Alloc>::value 8761378a5aeSMarshall Clow#endif 8771378a5aeSMarshall Clow > {}; 878e3fbe143SMarshall Clow 879dc3eb83dSMarshall Clow 880dc3eb83dSMarshall Clowtemplate <class _Tp, class _Alloc> 881dc3eb83dSMarshall Clowstruct __temp_value { 882dc3eb83dSMarshall Clow typedef allocator_traits<_Alloc> _Traits; 883dc3eb83dSMarshall Clow 884d108bf85SEric Fiselier typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v; 885dc3eb83dSMarshall Clow _Alloc &__a; 886dc3eb83dSMarshall Clow 887dc3eb83dSMarshall Clow _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } 888dc3eb83dSMarshall Clow _Tp & get() { return *__addr(); } 889dc3eb83dSMarshall Clow 890dc3eb83dSMarshall Clow template<class... _Args> 891f11c00d7SPeter Collingbourne _LIBCPP_NO_CFI 892f11c00d7SPeter Collingbourne __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) { 893f11c00d7SPeter Collingbourne _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)), 894f11c00d7SPeter Collingbourne _VSTD::forward<_Args>(__args)...); 895f11c00d7SPeter Collingbourne } 896dc3eb83dSMarshall Clow 897dc3eb83dSMarshall Clow ~__temp_value() { _Traits::destroy(__a, __addr()); } 898dc3eb83dSMarshall Clow }; 899dc3eb83dSMarshall Clow 90076b26852SMarshall Clowtemplate<typename _Alloc, typename = void, typename = void> 9010e22bf8cSMarshall Clowstruct __is_allocator : false_type {}; 9020e22bf8cSMarshall Clow 9030e22bf8cSMarshall Clowtemplate<typename _Alloc> 9040e22bf8cSMarshall Clowstruct __is_allocator<_Alloc, 90576b26852SMarshall Clow typename __void_t<typename _Alloc::value_type>::type, 90676b26852SMarshall Clow typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type 90776b26852SMarshall Clow > 9080e22bf8cSMarshall Clow : true_type {}; 9090e22bf8cSMarshall Clow 910d63dd874SEric Fiselier// __builtin_new_allocator -- A non-templated helper for allocating and 911d63dd874SEric Fiselier// deallocating memory using __builtin_operator_new and 912d63dd874SEric Fiselier// __builtin_operator_delete. It should be used in preference to 913d63dd874SEric Fiselier// `std::allocator<T>` to avoid additional instantiations. 914d63dd874SEric Fiselierstruct __builtin_new_allocator { 915d63dd874SEric Fiselier struct __builtin_new_deleter { 916d63dd874SEric Fiselier typedef void* pointer_type; 917d63dd874SEric Fiselier 918d63dd874SEric Fiselier _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align) 919d63dd874SEric Fiselier : __size_(__size), __align_(__align) {} 920d63dd874SEric Fiselier 921d63dd874SEric Fiselier void operator()(void* p) const _NOEXCEPT { 922d586f92cSArthur O'Dwyer _VSTD::__libcpp_deallocate(p, __size_, __align_); 923d63dd874SEric Fiselier } 924d63dd874SEric Fiselier 925d63dd874SEric Fiselier private: 926d63dd874SEric Fiselier size_t __size_; 927d63dd874SEric Fiselier size_t __align_; 928d63dd874SEric Fiselier }; 929d63dd874SEric Fiselier 930d63dd874SEric Fiselier typedef unique_ptr<void, __builtin_new_deleter> __holder_t; 931d63dd874SEric Fiselier 932d63dd874SEric Fiselier static __holder_t __allocate_bytes(size_t __s, size_t __align) { 933d586f92cSArthur O'Dwyer return __holder_t(_VSTD::__libcpp_allocate(__s, __align), 934d63dd874SEric Fiselier __builtin_new_deleter(__s, __align)); 935d63dd874SEric Fiselier } 936d63dd874SEric Fiselier 937d63dd874SEric Fiselier static void __deallocate_bytes(void* __p, size_t __s, 938d63dd874SEric Fiselier size_t __align) _NOEXCEPT { 939d586f92cSArthur O'Dwyer _VSTD::__libcpp_deallocate(__p, __s, __align); 940d63dd874SEric Fiselier } 941d63dd874SEric Fiselier 942d63dd874SEric Fiselier template <class _Tp> 943d63dd874SEric Fiselier _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE 944d63dd874SEric Fiselier static __holder_t __allocate_type(size_t __n) { 945d63dd874SEric Fiselier return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); 946d63dd874SEric Fiselier } 947d63dd874SEric Fiselier 948d63dd874SEric Fiselier template <class _Tp> 949d63dd874SEric Fiselier _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE 950d63dd874SEric Fiselier static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT { 951d63dd874SEric Fiselier __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); 952d63dd874SEric Fiselier } 953d63dd874SEric Fiselier}; 954d63dd874SEric Fiselier 955d63dd874SEric Fiselier 9563e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD 9573e519524SHoward Hinnant 958a016efb1SEric Fiselier_LIBCPP_POP_MACROS 959a016efb1SEric Fiselier 9600a06eb91SLouis Dionne#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 96195689243SLouis Dionne# include <__pstl_memory> 9620a06eb91SLouis Dionne#endif 9630a06eb91SLouis Dionne 9643e519524SHoward Hinnant#endif // _LIBCPP_MEMORY 965