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 <> 10287784cc6SLouis Dionneclass allocator<void> // 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> 15641bdf64dSLouis Dionneclass raw_storage_iterator // deprecated in C++17, removed in C++20 1571055cb91SLouis Dionne : public iterator<output_iterator_tag, void, void, void, void> // until C++17 1583e519524SHoward Hinnant{ 1593e519524SHoward Hinnantpublic: 16041bdf64dSLouis Dionne typedef output_iterator_tag iterator_category; 16141bdf64dSLouis Dionne typedef void value_type; 16241bdf64dSLouis Dionne typedef void difference_type; // until C++20 16341bdf64dSLouis Dionne typedef ptrdiff_t difference_type; // since C++20 16441bdf64dSLouis Dionne typedef void pointer; 16541bdf64dSLouis Dionne typedef void reference; 16641bdf64dSLouis Dionne 1673e519524SHoward Hinnant explicit raw_storage_iterator(OutputIterator x); 1683e519524SHoward Hinnant raw_storage_iterator& operator*(); 1693e519524SHoward Hinnant raw_storage_iterator& operator=(const T& element); 1703e519524SHoward Hinnant raw_storage_iterator& operator++(); 1713e519524SHoward Hinnant raw_storage_iterator operator++(int); 1723e519524SHoward Hinnant}; 1733e519524SHoward Hinnant 1743739fe79SHoward Hinnanttemplate <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept; 1753739fe79SHoward Hinnanttemplate <class T> void return_temporary_buffer(T* p) noexcept; 1763739fe79SHoward Hinnant 1773739fe79SHoward Hinnanttemplate <class T> T* addressof(T& r) noexcept; 1781c7fe126SMarshall Clowtemplate <class T> T* addressof(const T&& r) noexcept = delete; 1793e519524SHoward Hinnant 1803e519524SHoward Hinnanttemplate <class InputIterator, class ForwardIterator> 1813e519524SHoward HinnantForwardIterator 1823e519524SHoward Hinnantuninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); 1833e519524SHoward Hinnant 1843739fe79SHoward Hinnanttemplate <class InputIterator, class Size, class ForwardIterator> 1853739fe79SHoward HinnantForwardIterator 1863739fe79SHoward Hinnantuninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); 1873739fe79SHoward Hinnant 1883e519524SHoward Hinnanttemplate <class ForwardIterator, class T> 1893e519524SHoward Hinnantvoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); 1903e519524SHoward Hinnant 1913e519524SHoward Hinnanttemplate <class ForwardIterator, class Size, class T> 19248d05bd2SHoward HinnantForwardIterator 19348d05bd2SHoward Hinnantuninitialized_fill_n(ForwardIterator first, Size n, const T& x); 1943e519524SHoward Hinnant 1950724f8bfSLouis Dionnetemplate <class T, class ...Args> 1960724f8bfSLouis Dionneconstexpr T* construct_at(T* location, Args&& ...args); // since C++20 1970724f8bfSLouis Dionne 198e4d9c316SEric Fiseliertemplate <class T> 1990724f8bfSLouis Dionnevoid destroy_at(T* location); // constexpr in C++20 200e4d9c316SEric Fiselier 201e4d9c316SEric Fiseliertemplate <class ForwardIterator> 2020724f8bfSLouis Dionnevoid destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20 203e4d9c316SEric Fiselier 204e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size> 2050724f8bfSLouis DionneForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20 206e4d9c316SEric Fiselier 207e4d9c316SEric Fiseliertemplate <class InputIterator, class ForwardIterator> 208e4d9c316SEric Fiselier ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); 209e4d9c316SEric Fiselier 210e4d9c316SEric Fiseliertemplate <class InputIterator, class Size, class ForwardIterator> 211e4d9c316SEric Fiselier pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); 212e4d9c316SEric Fiselier 213e4d9c316SEric Fiseliertemplate <class ForwardIterator> 214e4d9c316SEric Fiselier void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); 215e4d9c316SEric Fiselier 216e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size> 217e4d9c316SEric Fiselier ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); 218e4d9c316SEric Fiselier 219e4d9c316SEric Fiseliertemplate <class ForwardIterator> 220e4d9c316SEric Fiselier void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); 221e4d9c316SEric Fiselier 222e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size> 223e4d9c316SEric Fiselier ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); 224e4d9c316SEric Fiselier 225ea5cd3b4SLouis Dionnetemplate <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17 2263e519524SHoward Hinnant 2273e519524SHoward Hinnanttemplate<class X> 228ea5cd3b4SLouis Dionneclass auto_ptr // deprecated in C++11, removed in C++17 2293e519524SHoward Hinnant{ 2303e519524SHoward Hinnantpublic: 2313e519524SHoward Hinnant typedef X element_type; 2323e519524SHoward Hinnant 2333e519524SHoward Hinnant explicit auto_ptr(X* p =0) throw(); 2343e519524SHoward Hinnant auto_ptr(auto_ptr&) throw(); 2353e519524SHoward Hinnant template<class Y> auto_ptr(auto_ptr<Y>&) throw(); 2363e519524SHoward Hinnant auto_ptr& operator=(auto_ptr&) throw(); 2373e519524SHoward Hinnant template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw(); 2383e519524SHoward Hinnant auto_ptr& operator=(auto_ptr_ref<X> r) throw(); 2393e519524SHoward Hinnant ~auto_ptr() throw(); 2403e519524SHoward Hinnant 2413e519524SHoward Hinnant typename add_lvalue_reference<X>::type operator*() const throw(); 2423e519524SHoward Hinnant X* operator->() const throw(); 2433e519524SHoward Hinnant X* get() const throw(); 2443e519524SHoward Hinnant X* release() throw(); 2453e519524SHoward Hinnant void reset(X* p =0) throw(); 2463e519524SHoward Hinnant 2473e519524SHoward Hinnant auto_ptr(auto_ptr_ref<X>) throw(); 2483e519524SHoward Hinnant template<class Y> operator auto_ptr_ref<Y>() throw(); 2493e519524SHoward Hinnant template<class Y> operator auto_ptr<Y>() throw(); 2503e519524SHoward Hinnant}; 2513e519524SHoward Hinnant 25220cc2a42SHoward Hinnanttemplate <class T> 25320cc2a42SHoward Hinnantstruct default_delete 25420cc2a42SHoward Hinnant{ 2553739fe79SHoward Hinnant constexpr default_delete() noexcept = default; 2563739fe79SHoward Hinnant template <class U> default_delete(const default_delete<U>&) noexcept; 25720cc2a42SHoward Hinnant 2583739fe79SHoward Hinnant void operator()(T*) const noexcept; 25920cc2a42SHoward Hinnant}; 26020cc2a42SHoward Hinnant 26120cc2a42SHoward Hinnanttemplate <class T> 26220cc2a42SHoward Hinnantstruct default_delete<T[]> 26320cc2a42SHoward Hinnant{ 2643739fe79SHoward Hinnant constexpr default_delete() noexcept = default; 2653739fe79SHoward Hinnant void operator()(T*) const noexcept; 26620cc2a42SHoward Hinnant template <class U> void operator()(U*) const = delete; 26720cc2a42SHoward Hinnant}; 26820cc2a42SHoward Hinnant 26920cc2a42SHoward Hinnanttemplate <class T, class D = default_delete<T>> 27020cc2a42SHoward Hinnantclass unique_ptr 27120cc2a42SHoward Hinnant{ 27220cc2a42SHoward Hinnantpublic: 27320cc2a42SHoward Hinnant typedef see below pointer; 27420cc2a42SHoward Hinnant typedef T element_type; 27520cc2a42SHoward Hinnant typedef D deleter_type; 27620cc2a42SHoward Hinnant 27720cc2a42SHoward Hinnant // constructors 2783739fe79SHoward Hinnant constexpr unique_ptr() noexcept; 2793739fe79SHoward Hinnant explicit unique_ptr(pointer p) noexcept; 2803739fe79SHoward Hinnant unique_ptr(pointer p, see below d1) noexcept; 2813739fe79SHoward Hinnant unique_ptr(pointer p, see below d2) noexcept; 2823739fe79SHoward Hinnant unique_ptr(unique_ptr&& u) noexcept; 2833739fe79SHoward Hinnant unique_ptr(nullptr_t) noexcept : unique_ptr() { } 28420cc2a42SHoward Hinnant template <class U, class E> 2853739fe79SHoward Hinnant unique_ptr(unique_ptr<U, E>&& u) noexcept; 28620cc2a42SHoward Hinnant template <class U> 287e67179bcSMarshall Clow unique_ptr(auto_ptr<U>&& u) noexcept; // removed in C++17 28820cc2a42SHoward Hinnant 28920cc2a42SHoward Hinnant // destructor 29020cc2a42SHoward Hinnant ~unique_ptr(); 29120cc2a42SHoward Hinnant 29220cc2a42SHoward Hinnant // assignment 2933739fe79SHoward Hinnant unique_ptr& operator=(unique_ptr&& u) noexcept; 2943739fe79SHoward Hinnant template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; 2953739fe79SHoward Hinnant unique_ptr& operator=(nullptr_t) noexcept; 29620cc2a42SHoward Hinnant 29720cc2a42SHoward Hinnant // observers 29820cc2a42SHoward Hinnant typename add_lvalue_reference<T>::type operator*() const; 2993739fe79SHoward Hinnant pointer operator->() const noexcept; 3003739fe79SHoward Hinnant pointer get() const noexcept; 3013739fe79SHoward Hinnant deleter_type& get_deleter() noexcept; 3023739fe79SHoward Hinnant const deleter_type& get_deleter() const noexcept; 3033739fe79SHoward Hinnant explicit operator bool() const noexcept; 30420cc2a42SHoward Hinnant 30520cc2a42SHoward Hinnant // modifiers 3063739fe79SHoward Hinnant pointer release() noexcept; 3073739fe79SHoward Hinnant void reset(pointer p = pointer()) noexcept; 3083739fe79SHoward Hinnant void swap(unique_ptr& u) noexcept; 30920cc2a42SHoward Hinnant}; 31020cc2a42SHoward Hinnant 31120cc2a42SHoward Hinnanttemplate <class T, class D> 31220cc2a42SHoward Hinnantclass unique_ptr<T[], D> 31320cc2a42SHoward Hinnant{ 31420cc2a42SHoward Hinnantpublic: 31520cc2a42SHoward Hinnant typedef implementation-defined pointer; 31620cc2a42SHoward Hinnant typedef T element_type; 31720cc2a42SHoward Hinnant typedef D deleter_type; 31820cc2a42SHoward Hinnant 31920cc2a42SHoward Hinnant // constructors 3203739fe79SHoward Hinnant constexpr unique_ptr() noexcept; 3213739fe79SHoward Hinnant explicit unique_ptr(pointer p) noexcept; 3223739fe79SHoward Hinnant unique_ptr(pointer p, see below d) noexcept; 3233739fe79SHoward Hinnant unique_ptr(pointer p, see below d) noexcept; 3243739fe79SHoward Hinnant unique_ptr(unique_ptr&& u) noexcept; 3253739fe79SHoward Hinnant unique_ptr(nullptr_t) noexcept : unique_ptr() { } 32620cc2a42SHoward Hinnant 32720cc2a42SHoward Hinnant // destructor 328b3371f6fSHoward Hinnant ~unique_ptr(); 32920cc2a42SHoward Hinnant 33020cc2a42SHoward Hinnant // assignment 3313739fe79SHoward Hinnant unique_ptr& operator=(unique_ptr&& u) noexcept; 3323739fe79SHoward Hinnant unique_ptr& operator=(nullptr_t) noexcept; 33320cc2a42SHoward Hinnant 33420cc2a42SHoward Hinnant // observers 33520cc2a42SHoward Hinnant T& operator[](size_t i) const; 3363739fe79SHoward Hinnant pointer get() const noexcept; 3373739fe79SHoward Hinnant deleter_type& get_deleter() noexcept; 3383739fe79SHoward Hinnant const deleter_type& get_deleter() const noexcept; 3393739fe79SHoward Hinnant explicit operator bool() const noexcept; 34020cc2a42SHoward Hinnant 34120cc2a42SHoward Hinnant // modifiers 3423739fe79SHoward Hinnant pointer release() noexcept; 3433739fe79SHoward Hinnant void reset(pointer p = pointer()) noexcept; 3443739fe79SHoward Hinnant void reset(nullptr_t) noexcept; 34520cc2a42SHoward Hinnant template <class U> void reset(U) = delete; 3463739fe79SHoward Hinnant void swap(unique_ptr& u) noexcept; 34720cc2a42SHoward Hinnant}; 34820cc2a42SHoward Hinnant 34920cc2a42SHoward Hinnanttemplate <class T, class D> 3503739fe79SHoward Hinnant void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; 35120cc2a42SHoward Hinnant 35220cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35320cc2a42SHoward Hinnant bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 35420cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35520cc2a42SHoward Hinnant bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 35620cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35720cc2a42SHoward Hinnant bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 35820cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 35920cc2a42SHoward Hinnant bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 36020cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 36120cc2a42SHoward Hinnant bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 36220cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2> 36320cc2a42SHoward Hinnant bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 36420cc2a42SHoward Hinnant 3653739fe79SHoward Hinnanttemplate <class T, class D> 3663739fe79SHoward Hinnant bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; 3673739fe79SHoward Hinnanttemplate <class T, class D> 3683739fe79SHoward Hinnant bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; 3693739fe79SHoward Hinnanttemplate <class T, class D> 3703739fe79SHoward Hinnant bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; 3713739fe79SHoward Hinnanttemplate <class T, class D> 3723739fe79SHoward Hinnant bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; 3733739fe79SHoward Hinnant 3743739fe79SHoward Hinnanttemplate <class T, class D> 3753739fe79SHoward Hinnant bool operator<(const unique_ptr<T, D>& x, nullptr_t); 3763739fe79SHoward Hinnanttemplate <class T, class D> 3773739fe79SHoward Hinnant bool operator<(nullptr_t, const unique_ptr<T, D>& y); 3783739fe79SHoward Hinnanttemplate <class T, class D> 3793739fe79SHoward Hinnant bool operator<=(const unique_ptr<T, D>& x, nullptr_t); 3803739fe79SHoward Hinnanttemplate <class T, class D> 3813739fe79SHoward Hinnant bool operator<=(nullptr_t, const unique_ptr<T, D>& y); 3823739fe79SHoward Hinnanttemplate <class T, class D> 3833739fe79SHoward Hinnant bool operator>(const unique_ptr<T, D>& x, nullptr_t); 3843739fe79SHoward Hinnanttemplate <class T, class D> 3853739fe79SHoward Hinnant bool operator>(nullptr_t, const unique_ptr<T, D>& y); 3863739fe79SHoward Hinnanttemplate <class T, class D> 3873739fe79SHoward Hinnant bool operator>=(const unique_ptr<T, D>& x, nullptr_t); 3883739fe79SHoward Hinnanttemplate <class T, class D> 3893739fe79SHoward Hinnant bool operator>=(nullptr_t, const unique_ptr<T, D>& y); 3903739fe79SHoward Hinnant 39120cc2a42SHoward Hinnantclass bad_weak_ptr 39220cc2a42SHoward Hinnant : public std::exception 39320cc2a42SHoward Hinnant{ 3943739fe79SHoward Hinnant bad_weak_ptr() noexcept; 39520cc2a42SHoward Hinnant}; 39620cc2a42SHoward Hinnant 39728d8ba5fSMarshall Clowtemplate<class T, class... Args> unique_ptr<T> make_unique(Args&&... args); // C++14 39828d8ba5fSMarshall Clowtemplate<class T> unique_ptr<T> make_unique(size_t n); // C++14 39928d8ba5fSMarshall Clowtemplate<class T, class... Args> unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] 40028d8ba5fSMarshall Clow 40148f36539SMarshall Clowtemplate<class E, class T, class Y, class D> 40248f36539SMarshall Clow basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p); 40348f36539SMarshall Clow 40420cc2a42SHoward Hinnanttemplate<class T> 40520cc2a42SHoward Hinnantclass shared_ptr 40620cc2a42SHoward Hinnant{ 40720cc2a42SHoward Hinnantpublic: 40820cc2a42SHoward Hinnant typedef T element_type; 40968436a9bSEric Fiselier typedef weak_ptr<T> weak_type; // C++17 41020cc2a42SHoward Hinnant 41120cc2a42SHoward Hinnant // constructors: 4123739fe79SHoward Hinnant constexpr shared_ptr() noexcept; 41320cc2a42SHoward Hinnant template<class Y> explicit shared_ptr(Y* p); 41420cc2a42SHoward Hinnant template<class Y, class D> shared_ptr(Y* p, D d); 41520cc2a42SHoward Hinnant template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); 41620cc2a42SHoward Hinnant template <class D> shared_ptr(nullptr_t p, D d); 41720cc2a42SHoward Hinnant template <class D, class A> shared_ptr(nullptr_t p, D d, A a); 4183739fe79SHoward Hinnant template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept; 4193739fe79SHoward Hinnant shared_ptr(const shared_ptr& r) noexcept; 4203739fe79SHoward Hinnant template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept; 4213739fe79SHoward Hinnant shared_ptr(shared_ptr&& r) noexcept; 4223739fe79SHoward Hinnant template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept; 42320cc2a42SHoward Hinnant template<class Y> explicit shared_ptr(const weak_ptr<Y>& r); 424e67179bcSMarshall Clow template<class Y> shared_ptr(auto_ptr<Y>&& r); // removed in C++17 42520cc2a42SHoward Hinnant template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r); 42620cc2a42SHoward Hinnant shared_ptr(nullptr_t) : shared_ptr() { } 42720cc2a42SHoward Hinnant 42820cc2a42SHoward Hinnant // destructor: 42920cc2a42SHoward Hinnant ~shared_ptr(); 43020cc2a42SHoward Hinnant 43120cc2a42SHoward Hinnant // assignment: 4323739fe79SHoward Hinnant shared_ptr& operator=(const shared_ptr& r) noexcept; 4333739fe79SHoward Hinnant template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept; 4343739fe79SHoward Hinnant shared_ptr& operator=(shared_ptr&& r) noexcept; 43520cc2a42SHoward Hinnant template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r); 436e67179bcSMarshall Clow template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17 43720cc2a42SHoward Hinnant template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r); 43820cc2a42SHoward Hinnant 43920cc2a42SHoward Hinnant // modifiers: 4403739fe79SHoward Hinnant void swap(shared_ptr& r) noexcept; 4413739fe79SHoward Hinnant void reset() noexcept; 44220cc2a42SHoward Hinnant template<class Y> void reset(Y* p); 44320cc2a42SHoward Hinnant template<class Y, class D> void reset(Y* p, D d); 44420cc2a42SHoward Hinnant template<class Y, class D, class A> void reset(Y* p, D d, A a); 44520cc2a42SHoward Hinnant 4463739fe79SHoward Hinnant // observers: 4473739fe79SHoward Hinnant T* get() const noexcept; 4483739fe79SHoward Hinnant T& operator*() const noexcept; 4493739fe79SHoward Hinnant T* operator->() const noexcept; 4503739fe79SHoward Hinnant long use_count() const noexcept; 4513739fe79SHoward Hinnant bool unique() const noexcept; 4523739fe79SHoward Hinnant explicit operator bool() const noexcept; 45336bc7178SMarshall Clow template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept; 45436bc7178SMarshall Clow template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept; 45520cc2a42SHoward Hinnant}; 45620cc2a42SHoward Hinnant 45783564056SLogan Smithtemplate<class T> 45883564056SLogan Smithshared_ptr(weak_ptr<T>) -> shared_ptr<T>; 45983564056SLogan Smithtemplate<class T, class D> 46083564056SLogan Smithshared_ptr(unique_ptr<T, D>) -> shared_ptr<T>; 46183564056SLogan Smith 46220cc2a42SHoward Hinnant// shared_ptr comparisons: 46320cc2a42SHoward Hinnanttemplate<class T, class U> 4643739fe79SHoward Hinnant bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 46520cc2a42SHoward Hinnanttemplate<class T, class U> 4663739fe79SHoward Hinnant bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 46720cc2a42SHoward Hinnanttemplate<class T, class U> 4683739fe79SHoward Hinnant bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 46920cc2a42SHoward Hinnanttemplate<class T, class U> 4703739fe79SHoward Hinnant bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 47120cc2a42SHoward Hinnanttemplate<class T, class U> 4723739fe79SHoward Hinnant bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 47320cc2a42SHoward Hinnanttemplate<class T, class U> 4743739fe79SHoward Hinnant bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 4753739fe79SHoward Hinnant 4763739fe79SHoward Hinnanttemplate <class T> 4773739fe79SHoward Hinnant bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept; 4783739fe79SHoward Hinnanttemplate <class T> 4793739fe79SHoward Hinnant bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept; 4803739fe79SHoward Hinnanttemplate <class T> 4813739fe79SHoward Hinnant bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept; 4823739fe79SHoward Hinnanttemplate <class T> 4833739fe79SHoward Hinnant bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept; 4843739fe79SHoward Hinnanttemplate <class T> 4853739fe79SHoward Hinnant bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept; 4863739fe79SHoward Hinnanttemplate <class T> 4873739fe79SHoward Hinnantbool operator<(nullptr_t, const shared_ptr<T>& y) noexcept; 4883739fe79SHoward Hinnanttemplate <class T> 4893739fe79SHoward Hinnant bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept; 4903739fe79SHoward Hinnanttemplate <class T> 4913739fe79SHoward Hinnant bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept; 4923739fe79SHoward Hinnanttemplate <class T> 4933739fe79SHoward Hinnant bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept; 4943739fe79SHoward Hinnanttemplate <class T> 4953739fe79SHoward Hinnant bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept; 4963739fe79SHoward Hinnanttemplate <class T> 4973739fe79SHoward Hinnant bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept; 4983739fe79SHoward Hinnanttemplate <class T> 4993739fe79SHoward Hinnant bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept; 50020cc2a42SHoward Hinnant 50120cc2a42SHoward Hinnant// shared_ptr specialized algorithms: 5023739fe79SHoward Hinnanttemplate<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept; 50320cc2a42SHoward Hinnant 50420cc2a42SHoward Hinnant// shared_ptr casts: 50520cc2a42SHoward Hinnanttemplate<class T, class U> 5063739fe79SHoward Hinnant shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept; 50720cc2a42SHoward Hinnanttemplate<class T, class U> 5083739fe79SHoward Hinnant shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept; 50920cc2a42SHoward Hinnanttemplate<class T, class U> 5103739fe79SHoward Hinnant shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept; 51120cc2a42SHoward Hinnant 51220cc2a42SHoward Hinnant// shared_ptr I/O: 51320cc2a42SHoward Hinnanttemplate<class E, class T, class Y> 51420cc2a42SHoward Hinnant basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p); 51520cc2a42SHoward Hinnant 51620cc2a42SHoward Hinnant// shared_ptr get_deleter: 5173739fe79SHoward Hinnanttemplate<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept; 51820cc2a42SHoward Hinnant 51920cc2a42SHoward Hinnanttemplate<class T, class... Args> 52020cc2a42SHoward Hinnant shared_ptr<T> make_shared(Args&&... args); 52120cc2a42SHoward Hinnanttemplate<class T, class A, class... Args> 52220cc2a42SHoward Hinnant shared_ptr<T> allocate_shared(const A& a, Args&&... args); 52320cc2a42SHoward Hinnant 52420cc2a42SHoward Hinnanttemplate<class T> 52520cc2a42SHoward Hinnantclass weak_ptr 52620cc2a42SHoward Hinnant{ 52720cc2a42SHoward Hinnantpublic: 52820cc2a42SHoward Hinnant typedef T element_type; 52920cc2a42SHoward Hinnant 53020cc2a42SHoward Hinnant // constructors 5313739fe79SHoward Hinnant constexpr weak_ptr() noexcept; 5323739fe79SHoward Hinnant template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept; 5333739fe79SHoward Hinnant weak_ptr(weak_ptr const& r) noexcept; 5343739fe79SHoward Hinnant template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept; 5354703f763SMarshall Clow weak_ptr(weak_ptr&& r) noexcept; // C++14 5364703f763SMarshall Clow template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14 53720cc2a42SHoward Hinnant 53820cc2a42SHoward Hinnant // destructor 53920cc2a42SHoward Hinnant ~weak_ptr(); 54020cc2a42SHoward Hinnant 54120cc2a42SHoward Hinnant // assignment 5423739fe79SHoward Hinnant weak_ptr& operator=(weak_ptr const& r) noexcept; 5433739fe79SHoward Hinnant template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept; 5443739fe79SHoward Hinnant template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept; 5454703f763SMarshall Clow weak_ptr& operator=(weak_ptr&& r) noexcept; // C++14 5464703f763SMarshall Clow template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14 54720cc2a42SHoward Hinnant 54820cc2a42SHoward Hinnant // modifiers 5493739fe79SHoward Hinnant void swap(weak_ptr& r) noexcept; 5503739fe79SHoward Hinnant void reset() noexcept; 55120cc2a42SHoward Hinnant 55220cc2a42SHoward Hinnant // observers 5533739fe79SHoward Hinnant long use_count() const noexcept; 5543739fe79SHoward Hinnant bool expired() const noexcept; 5553739fe79SHoward Hinnant shared_ptr<T> lock() const noexcept; 55636bc7178SMarshall Clow template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept; 55736bc7178SMarshall Clow template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept; 55820cc2a42SHoward Hinnant}; 55920cc2a42SHoward Hinnant 56083564056SLogan Smithtemplate<class T> 56183564056SLogan Smithweak_ptr(shared_ptr<T>) -> weak_ptr<T>; 56283564056SLogan Smith 56320cc2a42SHoward Hinnant// weak_ptr specialized algorithms: 5643739fe79SHoward Hinnanttemplate<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; 56520cc2a42SHoward Hinnant 56620cc2a42SHoward Hinnant// class owner_less: 56720cc2a42SHoward Hinnanttemplate<class T> struct owner_less; 56820cc2a42SHoward Hinnant 56920cc2a42SHoward Hinnanttemplate<class T> 57020cc2a42SHoward Hinnantstruct owner_less<shared_ptr<T> > 57120cc2a42SHoward Hinnant : binary_function<shared_ptr<T>, shared_ptr<T>, bool> 57220cc2a42SHoward Hinnant{ 57320cc2a42SHoward Hinnant typedef bool result_type; 57436bc7178SMarshall Clow bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept; 57536bc7178SMarshall Clow bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept; 57636bc7178SMarshall Clow bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept; 57720cc2a42SHoward Hinnant}; 57820cc2a42SHoward Hinnant 57920cc2a42SHoward Hinnanttemplate<class T> 58020cc2a42SHoward Hinnantstruct owner_less<weak_ptr<T> > 58120cc2a42SHoward Hinnant : binary_function<weak_ptr<T>, weak_ptr<T>, bool> 58220cc2a42SHoward Hinnant{ 58320cc2a42SHoward Hinnant typedef bool result_type; 58436bc7178SMarshall Clow bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept; 58536bc7178SMarshall Clow bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept; 58636bc7178SMarshall Clow bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept; 58736bc7178SMarshall Clow}; 58836bc7178SMarshall Clow 58936bc7178SMarshall Clowtemplate <> // Added in C++14 59036bc7178SMarshall Clowstruct owner_less<void> 59136bc7178SMarshall Clow{ 59236bc7178SMarshall Clow template <class _Tp, class _Up> 59336bc7178SMarshall Clow bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept; 59436bc7178SMarshall Clow template <class _Tp, class _Up> 59536bc7178SMarshall Clow bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept; 59636bc7178SMarshall Clow template <class _Tp, class _Up> 59736bc7178SMarshall Clow bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept; 59836bc7178SMarshall Clow template <class _Tp, class _Up> 59936bc7178SMarshall Clow bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept; 60036bc7178SMarshall Clow 60136bc7178SMarshall Clow typedef void is_transparent; 60220cc2a42SHoward Hinnant}; 60320cc2a42SHoward Hinnant 60420cc2a42SHoward Hinnanttemplate<class T> 60520cc2a42SHoward Hinnantclass enable_shared_from_this 60620cc2a42SHoward Hinnant{ 60720cc2a42SHoward Hinnantprotected: 6083739fe79SHoward Hinnant constexpr enable_shared_from_this() noexcept; 6093739fe79SHoward Hinnant enable_shared_from_this(enable_shared_from_this const&) noexcept; 6103739fe79SHoward Hinnant enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept; 61120cc2a42SHoward Hinnant ~enable_shared_from_this(); 61220cc2a42SHoward Hinnantpublic: 61320cc2a42SHoward Hinnant shared_ptr<T> shared_from_this(); 61420cc2a42SHoward Hinnant shared_ptr<T const> shared_from_this() const; 61520cc2a42SHoward Hinnant}; 61620cc2a42SHoward Hinnant 61720cc2a42SHoward Hinnanttemplate<class T> 61820cc2a42SHoward Hinnant bool atomic_is_lock_free(const shared_ptr<T>* p); 61920cc2a42SHoward Hinnanttemplate<class T> 62020cc2a42SHoward Hinnant shared_ptr<T> atomic_load(const shared_ptr<T>* p); 62120cc2a42SHoward Hinnanttemplate<class T> 62220cc2a42SHoward Hinnant shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo); 62320cc2a42SHoward Hinnanttemplate<class T> 62420cc2a42SHoward Hinnant void atomic_store(shared_ptr<T>* p, shared_ptr<T> r); 62520cc2a42SHoward Hinnanttemplate<class T> 62620cc2a42SHoward Hinnant void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); 62720cc2a42SHoward Hinnanttemplate<class T> 62820cc2a42SHoward Hinnant shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r); 62920cc2a42SHoward Hinnanttemplate<class T> 63020cc2a42SHoward Hinnant shared_ptr<T> 63120cc2a42SHoward Hinnant atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); 63220cc2a42SHoward Hinnanttemplate<class T> 63320cc2a42SHoward Hinnant bool 63420cc2a42SHoward Hinnant atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); 63520cc2a42SHoward Hinnanttemplate<class T> 63620cc2a42SHoward Hinnant bool 63720cc2a42SHoward Hinnant atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); 63820cc2a42SHoward Hinnanttemplate<class T> 63920cc2a42SHoward Hinnant bool 64020cc2a42SHoward Hinnant atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v, 64120cc2a42SHoward Hinnant shared_ptr<T> w, memory_order success, 64220cc2a42SHoward Hinnant memory_order failure); 64320cc2a42SHoward Hinnanttemplate<class T> 64420cc2a42SHoward Hinnant bool 64520cc2a42SHoward Hinnant atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v, 64620cc2a42SHoward Hinnant shared_ptr<T> w, memory_order success, 64720cc2a42SHoward Hinnant memory_order failure); 64820cc2a42SHoward Hinnant// Hash support 64920cc2a42SHoward Hinnanttemplate <class T> struct hash; 65020cc2a42SHoward Hinnanttemplate <class T, class D> struct hash<unique_ptr<T, D> >; 65120cc2a42SHoward Hinnanttemplate <class T> struct hash<shared_ptr<T> >; 65220cc2a42SHoward Hinnant 65340a01d53SMarshall Clowtemplate <class T, class Alloc> 65440a01d53SMarshall Clow inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value; 65540a01d53SMarshall Clow 65620cc2a42SHoward Hinnant// Pointer safety 65749e7be2eSLouis Dionneenum class pointer_safety { relaxed, preferred, strict }; // since C++11 65849e7be2eSLouis Dionnevoid declare_reachable(void *p); // since C++11 65949e7be2eSLouis Dionnetemplate <class T> T *undeclare_reachable(T *p); // since C++11 66049e7be2eSLouis Dionnevoid declare_no_pointers(char *p, size_t n); // since C++11 66149e7be2eSLouis Dionnevoid undeclare_no_pointers(char *p, size_t n); // since C++11 66249e7be2eSLouis Dionnepointer_safety get_pointer_safety() noexcept; // since C++11 66320cc2a42SHoward Hinnant 6643e519524SHoward Hinnantvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space); 6653e519524SHoward Hinnant 6663e519524SHoward Hinnant} // std 6673e519524SHoward Hinnant 6683e519524SHoward Hinnant*/ 6693e519524SHoward Hinnant 6703e519524SHoward Hinnant#include <__config> 6713e519524SHoward Hinnant#include <__functional_base> 672f992cfbaSLouis Dionne#include <__memory/addressof.h> 673e98060faSLouis Dionne#include <__memory/allocation_guard.h> 6740b439e4cSLouis Dionne#include <__memory/allocator.h> 675050b064fSChristopher Di Bella#include <__memory/allocator_arg_t.h> 6767ad49aecSLouis Dionne#include <__memory/allocator_traits.h> 6779b0a3388SLouis Dionne#include <__memory/compressed_pair.h> 678f992cfbaSLouis Dionne#include <__memory/construct_at.h> 6797f1963dcSLouis Dionne#include <__memory/pointer_safety.h> 6807ad49aecSLouis Dionne#include <__memory/pointer_traits.h> 681be54341cSLouis Dionne#include <__memory/raw_storage_iterator.h> 682916fecb4SLouis Dionne#include <__memory/shared_ptr.h> 6836a1ac88fSLouis Dionne#include <__memory/temporary_buffer.h> 6844f9b2469SLouis Dionne#include <__memory/uninitialized_algorithms.h> 68521d6636dSLouis Dionne#include <__memory/unique_ptr.h> 686050b064fSChristopher Di Bella#include <__memory/uses_allocator.h> 687bfbd73f8SArthur O'Dwyer#include <compare> 688bfbd73f8SArthur O'Dwyer#include <cstddef> 689bfbd73f8SArthur O'Dwyer#include <cstdint> 690bfbd73f8SArthur O'Dwyer#include <cstring> 691bfbd73f8SArthur O'Dwyer#include <iosfwd> 692bfbd73f8SArthur O'Dwyer#include <iterator> 693bfbd73f8SArthur O'Dwyer#include <new> 694bfbd73f8SArthur O'Dwyer#include <stdexcept> 695bfbd73f8SArthur O'Dwyer#include <tuple> 696bfbd73f8SArthur O'Dwyer#include <type_traits> 697bfbd73f8SArthur O'Dwyer#include <typeinfo> 698bfbd73f8SArthur O'Dwyer#include <utility> 699f56972e2SMarshall Clow#include <version> 700d77851e8SHoward Hinnant 701207d58bfSLouis Dionne#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 702207d58bfSLouis Dionne# include <__memory/auto_ptr.h> 703207d58bfSLouis Dionne#endif 704207d58bfSLouis Dionne 705073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 7063e519524SHoward Hinnant#pragma GCC system_header 707073458b1SHoward Hinnant#endif 7083e519524SHoward Hinnant 709a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS 710a016efb1SEric Fiselier#include <__undef_macros> 711a016efb1SEric Fiselier 712a016efb1SEric Fiselier 7133e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 7143e519524SHoward Hinnant 715d9a4f936SLouis Dionnetemplate <class _Alloc, class _Ptr> 716d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 717d9a4f936SLouis Dionnevoid __construct_forward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) { 718d9a4f936SLouis Dionne static_assert(__is_cpp17_move_insertable<_Alloc>::value, 719e9eb9999SArthur O'Dwyer "The specified type does not meet the requirements of Cpp17MoveInsertable"); 720d9a4f936SLouis Dionne typedef allocator_traits<_Alloc> _Traits; 721d9a4f936SLouis Dionne for (; __begin1 != __end1; ++__begin1, (void)++__begin2) { 722d9a4f936SLouis Dionne _Traits::construct(__a, _VSTD::__to_address(__begin2), 723d9a4f936SLouis Dionne#ifdef _LIBCPP_NO_EXCEPTIONS 724d9a4f936SLouis Dionne _VSTD::move(*__begin1) 725d9a4f936SLouis Dionne#else 726d9a4f936SLouis Dionne _VSTD::move_if_noexcept(*__begin1) 727d9a4f936SLouis Dionne#endif 728d9a4f936SLouis Dionne ); 729d9a4f936SLouis Dionne } 730d9a4f936SLouis Dionne} 731d9a4f936SLouis Dionne 732d9a4f936SLouis Dionnetemplate <class _Alloc, class _Tp, typename enable_if< 733d9a4f936SLouis Dionne (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) && 734d9a4f936SLouis Dionne is_trivially_move_constructible<_Tp>::value 735d9a4f936SLouis Dionne>::type> 736d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 737d9a4f936SLouis Dionnevoid __construct_forward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) { 738d9a4f936SLouis Dionne ptrdiff_t _Np = __end1 - __begin1; 739d9a4f936SLouis Dionne if (_Np > 0) { 740d9a4f936SLouis Dionne _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp)); 741d9a4f936SLouis Dionne __begin2 += _Np; 742d9a4f936SLouis Dionne } 743d9a4f936SLouis Dionne} 744d9a4f936SLouis Dionne 745d9a4f936SLouis Dionnetemplate <class _Alloc, class _Iter, class _Ptr> 746d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 747d9a4f936SLouis Dionnevoid __construct_range_forward(_Alloc& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2) { 748d9a4f936SLouis Dionne typedef allocator_traits<_Alloc> _Traits; 749d9a4f936SLouis Dionne for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) { 750d9a4f936SLouis Dionne _Traits::construct(__a, _VSTD::__to_address(__begin2), *__begin1); 751d9a4f936SLouis Dionne } 752d9a4f936SLouis Dionne} 753d9a4f936SLouis Dionne 754d9a4f936SLouis Dionnetemplate <class _Alloc, class _Source, class _Dest, 755d9a4f936SLouis Dionne class _RawSource = typename remove_const<_Source>::type, 756d9a4f936SLouis Dionne class _RawDest = typename remove_const<_Dest>::type, 757d9a4f936SLouis Dionne class = 758d9a4f936SLouis Dionne typename enable_if< 759d9a4f936SLouis Dionne is_trivially_copy_constructible<_Dest>::value && 760d9a4f936SLouis Dionne is_same<_RawSource, _RawDest>::value && 761d9a4f936SLouis Dionne (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Dest*, _Source&>::value) 762d9a4f936SLouis Dionne >::type> 763d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 764d9a4f936SLouis Dionnevoid __construct_range_forward(_Alloc&, _Source* __begin1, _Source* __end1, _Dest*& __begin2) { 765d9a4f936SLouis Dionne ptrdiff_t _Np = __end1 - __begin1; 766d9a4f936SLouis Dionne if (_Np > 0) { 767d9a4f936SLouis Dionne _VSTD::memcpy(const_cast<_RawDest*>(__begin2), __begin1, _Np * sizeof(_Dest)); 768d9a4f936SLouis Dionne __begin2 += _Np; 769d9a4f936SLouis Dionne } 770d9a4f936SLouis Dionne} 771d9a4f936SLouis Dionne 772d9a4f936SLouis Dionnetemplate <class _Alloc, class _Ptr> 773d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 774d9a4f936SLouis Dionnevoid __construct_backward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) { 775d9a4f936SLouis Dionne static_assert(__is_cpp17_move_insertable<_Alloc>::value, 776d9a4f936SLouis Dionne "The specified type does not meet the requirements of Cpp17MoveInsertable"); 777d9a4f936SLouis Dionne typedef allocator_traits<_Alloc> _Traits; 778d9a4f936SLouis Dionne while (__end1 != __begin1) { 779d9a4f936SLouis Dionne _Traits::construct(__a, _VSTD::__to_address(__end2 - 1), 780d9a4f936SLouis Dionne#ifdef _LIBCPP_NO_EXCEPTIONS 781d9a4f936SLouis Dionne _VSTD::move(*--__end1) 782d9a4f936SLouis Dionne#else 783d9a4f936SLouis Dionne _VSTD::move_if_noexcept(*--__end1) 784d9a4f936SLouis Dionne#endif 785d9a4f936SLouis Dionne ); 786d9a4f936SLouis Dionne --__end2; 787d9a4f936SLouis Dionne } 788d9a4f936SLouis Dionne} 789d9a4f936SLouis Dionne 790d9a4f936SLouis Dionnetemplate <class _Alloc, class _Tp, class = typename enable_if< 791d9a4f936SLouis Dionne (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) && 792d9a4f936SLouis Dionne is_trivially_move_constructible<_Tp>::value 793d9a4f936SLouis Dionne>::type> 794d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY 795d9a4f936SLouis Dionnevoid __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) { 796d9a4f936SLouis Dionne ptrdiff_t _Np = __end1 - __begin1; 797d9a4f936SLouis Dionne __end2 -= _Np; 798d9a4f936SLouis Dionne if (_Np > 0) 799*2e4755ffSLouis Dionne _VSTD::memcpy(static_cast<void*>(__end2), static_cast<void const*>(__begin1), _Np * sizeof(_Tp)); 800d9a4f936SLouis Dionne} 801d9a4f936SLouis Dionne 8023e519524SHoward Hinnantstruct __destruct_n 8033e519524SHoward Hinnant{ 8043e519524SHoward Hinnantprivate: 8059ffacf3dSEric Fiselier size_t __size_; 8063e519524SHoward Hinnant 8073e519524SHoward Hinnant template <class _Tp> 8083739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT 8099ffacf3dSEric Fiselier {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();} 8103e519524SHoward Hinnant 8113e519524SHoward Hinnant template <class _Tp> 8123739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT 8133e519524SHoward Hinnant {} 8143e519524SHoward Hinnant 8153739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT 8169ffacf3dSEric Fiselier {++__size_;} 8173739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT 8183e519524SHoward Hinnant {} 8193e519524SHoward Hinnant 8203739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT 8219ffacf3dSEric Fiselier {__size_ = __s;} 8223739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT 8233e519524SHoward Hinnant {} 8243e519524SHoward Hinnantpublic: 8253739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT 8269ffacf3dSEric Fiselier : __size_(__s) {} 8273e519524SHoward Hinnant 8283e519524SHoward Hinnant template <class _Tp> 829527a7fdfSBruce Mitchener _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT 830ca740483SHoward Hinnant {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 8313e519524SHoward Hinnant 8323e519524SHoward Hinnant template <class _Tp> 8333739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT 834ca740483SHoward Hinnant {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 8353e519524SHoward Hinnant 8363e519524SHoward Hinnant template <class _Tp> 8373739fe79SHoward Hinnant _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT 838ca740483SHoward Hinnant {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 8393e519524SHoward Hinnant}; 8403e519524SHoward Hinnant 841f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space); 8423e519524SHoward Hinnant 843e3fbe143SMarshall Clow// --- Helper for container swap -- 844e3fbe143SMarshall Clowtemplate <typename _Alloc> 845e3fbe143SMarshall Clow_LIBCPP_INLINE_VISIBILITY 846e3fbe143SMarshall Clowvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) 847e3fbe143SMarshall Clow#if _LIBCPP_STD_VER >= 14 848e3fbe143SMarshall Clow _NOEXCEPT 849e3fbe143SMarshall Clow#else 850e3fbe143SMarshall Clow _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) 851e3fbe143SMarshall Clow#endif 852e3fbe143SMarshall Clow{ 853e3fbe143SMarshall Clow using _VSTD::swap; 854e3fbe143SMarshall Clow swap(__a1, __a2); 855e3fbe143SMarshall Clow} 856e3fbe143SMarshall Clow 857e3fbe143SMarshall Clowtemplate <typename _Alloc> 85889dd1dd2SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 859e3fbe143SMarshall Clowvoid __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} 860e3fbe143SMarshall Clow 8616e965df6SArthur O'Dwyertemplate <typename _Alloc> 8626e965df6SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY 8636e965df6SArthur O'Dwyervoid __swap_allocator(_Alloc & __a1, _Alloc & __a2) 8646e965df6SArthur O'Dwyer#if _LIBCPP_STD_VER >= 14 8656e965df6SArthur O'Dwyer _NOEXCEPT 8666e965df6SArthur O'Dwyer#else 8676e965df6SArthur O'Dwyer _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) 8686e965df6SArthur O'Dwyer#endif 8696e965df6SArthur O'Dwyer{ 8706e965df6SArthur O'Dwyer _VSTD::__swap_allocator(__a1, __a2, 8716491d99eSArthur O'Dwyer integral_constant<bool, allocator_traits<_Alloc>::propagate_on_container_swap::value>()); 8726e965df6SArthur O'Dwyer} 8736e965df6SArthur O'Dwyer 8741378a5aeSMarshall Clowtemplate <typename _Alloc, typename _Traits=allocator_traits<_Alloc> > 8751378a5aeSMarshall Clowstruct __noexcept_move_assign_container : public integral_constant<bool, 8761378a5aeSMarshall Clow _Traits::propagate_on_container_move_assignment::value 8771378a5aeSMarshall Clow#if _LIBCPP_STD_VER > 14 8781378a5aeSMarshall Clow || _Traits::is_always_equal::value 8791378a5aeSMarshall Clow#else 8801378a5aeSMarshall Clow && is_nothrow_move_assignable<_Alloc>::value 8811378a5aeSMarshall Clow#endif 8821378a5aeSMarshall Clow > {}; 883e3fbe143SMarshall Clow 884dc3eb83dSMarshall Clow 885dc3eb83dSMarshall Clowtemplate <class _Tp, class _Alloc> 886dc3eb83dSMarshall Clowstruct __temp_value { 887dc3eb83dSMarshall Clow typedef allocator_traits<_Alloc> _Traits; 888dc3eb83dSMarshall Clow 889d108bf85SEric Fiselier typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v; 890dc3eb83dSMarshall Clow _Alloc &__a; 891dc3eb83dSMarshall Clow 892dc3eb83dSMarshall Clow _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } 893dc3eb83dSMarshall Clow _Tp & get() { return *__addr(); } 894dc3eb83dSMarshall Clow 895dc3eb83dSMarshall Clow template<class... _Args> 896f11c00d7SPeter Collingbourne _LIBCPP_NO_CFI 897f11c00d7SPeter Collingbourne __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) { 898f11c00d7SPeter Collingbourne _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)), 899f11c00d7SPeter Collingbourne _VSTD::forward<_Args>(__args)...); 900f11c00d7SPeter Collingbourne } 901dc3eb83dSMarshall Clow 902dc3eb83dSMarshall Clow ~__temp_value() { _Traits::destroy(__a, __addr()); } 903dc3eb83dSMarshall Clow }; 904dc3eb83dSMarshall Clow 90576b26852SMarshall Clowtemplate<typename _Alloc, typename = void, typename = void> 9060e22bf8cSMarshall Clowstruct __is_allocator : false_type {}; 9070e22bf8cSMarshall Clow 9080e22bf8cSMarshall Clowtemplate<typename _Alloc> 9090e22bf8cSMarshall Clowstruct __is_allocator<_Alloc, 91076b26852SMarshall Clow typename __void_t<typename _Alloc::value_type>::type, 911ab3fcc50SArthur O'Dwyer typename __void_t<decltype(declval<_Alloc&>().allocate(size_t(0)))>::type 91276b26852SMarshall Clow > 9130e22bf8cSMarshall Clow : true_type {}; 9140e22bf8cSMarshall Clow 915d63dd874SEric Fiselier// __builtin_new_allocator -- A non-templated helper for allocating and 916d63dd874SEric Fiselier// deallocating memory using __builtin_operator_new and 917d63dd874SEric Fiselier// __builtin_operator_delete. It should be used in preference to 918d63dd874SEric Fiselier// `std::allocator<T>` to avoid additional instantiations. 919d63dd874SEric Fiselierstruct __builtin_new_allocator { 920d63dd874SEric Fiselier struct __builtin_new_deleter { 921d63dd874SEric Fiselier typedef void* pointer_type; 922d63dd874SEric Fiselier 923d63dd874SEric Fiselier _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align) 924d63dd874SEric Fiselier : __size_(__size), __align_(__align) {} 925d63dd874SEric Fiselier 926d63dd874SEric Fiselier void operator()(void* p) const _NOEXCEPT { 927d586f92cSArthur O'Dwyer _VSTD::__libcpp_deallocate(p, __size_, __align_); 928d63dd874SEric Fiselier } 929d63dd874SEric Fiselier 930d63dd874SEric Fiselier private: 931d63dd874SEric Fiselier size_t __size_; 932d63dd874SEric Fiselier size_t __align_; 933d63dd874SEric Fiselier }; 934d63dd874SEric Fiselier 935d63dd874SEric Fiselier typedef unique_ptr<void, __builtin_new_deleter> __holder_t; 936d63dd874SEric Fiselier 937d63dd874SEric Fiselier static __holder_t __allocate_bytes(size_t __s, size_t __align) { 938d586f92cSArthur O'Dwyer return __holder_t(_VSTD::__libcpp_allocate(__s, __align), 939d63dd874SEric Fiselier __builtin_new_deleter(__s, __align)); 940d63dd874SEric Fiselier } 941d63dd874SEric Fiselier 942d63dd874SEric Fiselier static void __deallocate_bytes(void* __p, size_t __s, 943d63dd874SEric Fiselier size_t __align) _NOEXCEPT { 944d586f92cSArthur O'Dwyer _VSTD::__libcpp_deallocate(__p, __s, __align); 945d63dd874SEric Fiselier } 946d63dd874SEric Fiselier 947d63dd874SEric Fiselier template <class _Tp> 948d63dd874SEric Fiselier _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE 949d63dd874SEric Fiselier static __holder_t __allocate_type(size_t __n) { 950d63dd874SEric Fiselier return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); 951d63dd874SEric Fiselier } 952d63dd874SEric Fiselier 953d63dd874SEric Fiselier template <class _Tp> 954d63dd874SEric Fiselier _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE 955d63dd874SEric Fiselier static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT { 956d63dd874SEric Fiselier __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); 957d63dd874SEric Fiselier } 958d63dd874SEric Fiselier}; 959d63dd874SEric Fiselier 960d63dd874SEric Fiselier 9613e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD 9623e519524SHoward Hinnant 963a016efb1SEric Fiselier_LIBCPP_POP_MACROS 964a016efb1SEric Fiselier 9650a06eb91SLouis Dionne#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 96695689243SLouis Dionne# include <__pstl_memory> 9670a06eb91SLouis Dionne#endif 9680a06eb91SLouis Dionne 9693e519524SHoward Hinnant#endif // _LIBCPP_MEMORY 970