1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_MEMORY 11#define _LIBCPP_MEMORY 12 13/* 14 memory synopsis 15 16namespace std 17{ 18 19struct allocator_arg_t { }; 20inline constexpr allocator_arg_t allocator_arg = allocator_arg_t(); 21 22template <class T, class Alloc> struct uses_allocator; 23 24template <class Ptr> 25struct pointer_traits 26{ 27 typedef Ptr pointer; 28 typedef <details> element_type; 29 typedef <details> difference_type; 30 31 template <class U> using rebind = <details>; 32 33 static pointer pointer_to(<details>); 34}; 35 36template <class T> 37struct pointer_traits<T*> 38{ 39 typedef T* pointer; 40 typedef T element_type; 41 typedef ptrdiff_t difference_type; 42 43 template <class U> using rebind = U*; 44 45 static pointer pointer_to(<details>) noexcept; // constexpr in C++20 46}; 47 48template <class T> constexpr T* to_address(T* p) noexcept; // C++20 49template <class Ptr> constexpr auto to_address(const Ptr& p) noexcept; // C++20 50 51template <class Alloc> 52struct allocator_traits 53{ 54 typedef Alloc allocator_type; 55 typedef typename allocator_type::value_type 56 value_type; 57 58 typedef Alloc::pointer | value_type* pointer; 59 typedef Alloc::const_pointer 60 | pointer_traits<pointer>::rebind<const value_type> 61 const_pointer; 62 typedef Alloc::void_pointer 63 | pointer_traits<pointer>::rebind<void> 64 void_pointer; 65 typedef Alloc::const_void_pointer 66 | pointer_traits<pointer>::rebind<const void> 67 const_void_pointer; 68 typedef Alloc::difference_type 69 | pointer_traits<pointer>::difference_type 70 difference_type; 71 typedef Alloc::size_type 72 | make_unsigned<difference_type>::type 73 size_type; 74 typedef Alloc::propagate_on_container_copy_assignment 75 | false_type propagate_on_container_copy_assignment; 76 typedef Alloc::propagate_on_container_move_assignment 77 | false_type propagate_on_container_move_assignment; 78 typedef Alloc::propagate_on_container_swap 79 | false_type propagate_on_container_swap; 80 typedef Alloc::is_always_equal 81 | is_empty is_always_equal; 82 83 template <class T> using rebind_alloc = Alloc::rebind<T>::other | Alloc<T, Args...>; 84 template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>; 85 86 static pointer allocate(allocator_type& a, size_type n); // constexpr and [[nodiscard]] in C++20 87 static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20 88 89 static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20 90 91 template <class T, class... Args> 92 static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20 93 94 template <class T> 95 static void destroy(allocator_type& a, T* p); // constexpr in C++20 96 97 static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20 98 static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20 99}; 100 101template <> 102class allocator<void> // removed in C++20 103{ 104public: 105 typedef void* pointer; 106 typedef const void* const_pointer; 107 typedef void value_type; 108 109 template <class _Up> struct rebind {typedef allocator<_Up> other;}; 110}; 111 112template <class T> 113class allocator 114{ 115public: 116 typedef size_t size_type; 117 typedef ptrdiff_t difference_type; 118 typedef T* pointer; // deprecated in C++17, removed in C++20 119 typedef const T* const_pointer; // deprecated in C++17, removed in C++20 120 typedef typename add_lvalue_reference<T>::type 121 reference; // deprecated in C++17, removed in C++20 122 typedef typename add_lvalue_reference<const T>::type 123 const_reference; // deprecated in C++17, removed in C++20 124 125 typedef T value_type; 126 127 template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20 128 129 typedef true_type propagate_on_container_move_assignment; 130 typedef true_type is_always_equal; 131 132 constexpr allocator() noexcept; // constexpr in C++20 133 constexpr allocator(const allocator&) noexcept; // constexpr in C++20 134 template <class U> 135 constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20 136 ~allocator(); // constexpr in C++20 137 pointer address(reference x) const noexcept; // deprecated in C++17, removed in C++20 138 const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20 139 T* allocate(size_t n, const void* hint); // deprecated in C++17, removed in C++20 140 T* allocate(size_t n); // constexpr in C++20 141 void deallocate(T* p, size_t n) noexcept; // constexpr in C++20 142 size_type max_size() const noexcept; // deprecated in C++17, removed in C++20 143 template<class U, class... Args> 144 void construct(U* p, Args&&... args); // deprecated in C++17, removed in C++20 145 template <class U> 146 void destroy(U* p); // deprecated in C++17, removed in C++20 147}; 148 149template <class T, class U> 150bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20 151 152template <class T, class U> 153bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20 154 155template <class OutputIterator, class T> 156class raw_storage_iterator // deprecated in C++17, removed in C++20 157 : public iterator<output_iterator_tag, void, void, void, void> // until C++17 158{ 159public: 160 typedef output_iterator_tag iterator_category; 161 typedef void value_type; 162 typedef void difference_type; // until C++20 163 typedef ptrdiff_t difference_type; // since C++20 164 typedef void pointer; 165 typedef void reference; 166 167 explicit raw_storage_iterator(OutputIterator x); 168 raw_storage_iterator& operator*(); 169 raw_storage_iterator& operator=(const T& element); 170 raw_storage_iterator& operator++(); 171 raw_storage_iterator operator++(int); 172}; 173 174template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept; 175template <class T> void return_temporary_buffer(T* p) noexcept; 176 177template <class T> T* addressof(T& r) noexcept; 178template <class T> T* addressof(const T&& r) noexcept = delete; 179 180template <class InputIterator, class ForwardIterator> 181ForwardIterator 182uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result); 183 184namespace ranges { 185 186template<class InputIterator, class OutputIterator> 187using uninitialized_copy_result = in_out_result<InputIterator, OutputIterator>; // since C++20 188 189template<input_iterator InputIterator, sentinel-for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel2> 190 requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>> 191uninitialized_copy_result<InputIterator, OutputIterator> 192uninitialized_copy(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20 193 194template<input_range InputRange, nothrow-forward-range OutputRange> 195 requires constructible_from<range_value_t<OutputRange>, range_reference_t<InputRange>> 196uninitialized_copy_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>> 197uninitialized_copy(InputRange&& in_range, OutputRange&& out_range); // since C++20 198 199} 200 201template <class InputIterator, class Size, class ForwardIterator> 202ForwardIterator 203uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); 204 205namespace ranges { 206 207template<class InputIterator, class OutputIterator> 208using uninitialized_copy_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20 209 210template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel> 211 requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>> 212uninitialized_copy_n_result<InputIterator, OutputIterator> 213uninitialized_copy_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20 214 215} 216 217template <class ForwardIterator, class T> 218void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); 219 220namespace ranges { 221 222template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel, class T> 223 requires constructible_from<iter_value_t<ForwardIterator>, const T&> 224ForwardIterator uninitialized_fill(ForwardIterator first, Sentinel last, const T& x); // since C++20 225 226template <nothrow-forward-range ForwardRange, class T> 227 requires constructible_from<range_value_t<ForwardRange>, const T&> 228borrowed_iterator_t<ForwardRange> uninitialized_fill(ForwardRange&& range, const T& x); // since C++20 229 230} 231 232template <class ForwardIterator, class Size, class T> 233ForwardIterator 234uninitialized_fill_n(ForwardIterator first, Size n, const T& x); 235 236namespace ranges { 237 238template <nothrow-forward-iterator ForwardIterator, class T> 239 requires constructible_from<iter_value_t<ForwardIterator>, const T&> 240ForwardIterator uninitialized_fill_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 241 242} 243 244template <class T, class ...Args> 245constexpr T* construct_at(T* location, Args&& ...args); // since C++20 246 247namespace ranges { 248 template<class T, class... Args> 249 constexpr T* construct_at(T* location, Args&&... args); // since C++20 250} 251 252template <class T> 253void destroy_at(T* location); // constexpr in C++20 254 255namespace ranges { 256 template<destructible T> 257 constexpr void destroy_at(T* location) noexcept; // since C++20 258} 259 260template <class ForwardIterator> 261void destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20 262 263namespace ranges { 264 template<nothrow-input-iterator InputIterator, nothrow-sentinel-for<InputIterator> Sentinel> 265 requires destructible<iter_value_t<InputIterator>> 266 constexpr InputIterator destroy(InputIterator first, Sentinel last) noexcept; // since C++20 267 template<nothrow-input-range InputRange> 268 requires destructible<range_value_t<InputRange>> 269 constexpr borrowed_iterator_t<InputRange> destroy(InputRange&& range) noexcept; // since C++20 270} 271 272template <class ForwardIterator, class Size> 273ForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20 274 275namespace ranges { 276 template<nothrow-input-iterator InputIterator> 277 requires destructible<iter_value_t<InputIterator>> 278 constexpr InputIterator destroy_n(InputIterator first, iter_difference_t<InputIterator> n) noexcept; // since C++20 279} 280 281template <class InputIterator, class ForwardIterator> 282 ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); 283 284namespace ranges { 285 286template<class InputIterator, class OutputIterator> 287using uninitialized_move_result = in_out_result<InputIterator, OutputIterator>; // since C++20 288 289template <input_iterator InputIterator, sentinel_for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<O> Sentinel2> 290 requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>> 291uninitialized_move_result<InputIterator, OutputIterator> 292uninitialized_move(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20 293 294template<input_range InputRange, nothrow-forward-range OutputRange> 295 requires constructible_from<range_value_t<OutputRange>, range_rvalue_reference_t<InputRange>> 296uninitialized_move_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>> 297uninitialized_move(InputRange&& in_range, OutputRange&& out_range); // since C++20 298 299} 300 301template <class InputIterator, class Size, class ForwardIterator> 302 pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); 303 304namespace ranges { 305 306template<class InputIterator, class OutputIterator> 307using uninitialized_move_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20 308 309template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel> 310 requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>> 311uninitialized_move_n_result<InputIterator, OutputIterator> 312uninitialized_move_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20 313 314} 315 316template <class ForwardIterator> 317 void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); 318 319namespace ranges { 320 321template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel> 322 requires default_initializable<iter_value_t<ForwardIterator>> 323 ForwardIterator uninitialized_value_construct(ForwardIterator first, Sentinel last); // since C++20 324 325template <nothrow-forward-range ForwardRange> 326 requires default_initializable<range_value_t<ForwardRange>> 327 borrowed_iterator_t<ForwardRange> uninitialized_value_construct(ForwardRange&& r); // since C++20 328 329} 330 331template <class ForwardIterator, class Size> 332 ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); 333 334namespace ranges { 335 336template <nothrow-forward-iterator ForwardIterator> 337 requires default_initializable<iter_value_t<ForwardIterator>> 338 ForwardIterator uninitialized_value_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 339 340} 341 342template <class ForwardIterator> 343 void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); 344 345namespace ranges { 346 347template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel> 348 requires default_initializable<iter_value_t<ForwardIterator>> 349 ForwardIterator uninitialized_default_construct(ForwardIterator first, Sentinel last); // since C++20 350 351template <nothrow-forward-range ForwardRange> 352 requires default_initializable<range_value_t<ForwardRange>> 353 borrowed_iterator_t<ForwardRange> uninitialized_default_construct(ForwardRange&& r); // since C++20 354 355} 356 357template <class ForwardIterator, class Size> 358 ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); 359 360namespace ranges { 361 362template <nothrow-forward-iterator ForwardIterator> 363 requires default_initializable<iter_value_t<ForwardIterator>> 364 ForwardIterator uninitialized_default_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20 365 366} 367 368template <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17 369 370template<class X> 371class auto_ptr // deprecated in C++11, removed in C++17 372{ 373public: 374 typedef X element_type; 375 376 explicit auto_ptr(X* p =0) throw(); 377 auto_ptr(auto_ptr&) throw(); 378 template<class Y> auto_ptr(auto_ptr<Y>&) throw(); 379 auto_ptr& operator=(auto_ptr&) throw(); 380 template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw(); 381 auto_ptr& operator=(auto_ptr_ref<X> r) throw(); 382 ~auto_ptr() throw(); 383 384 typename add_lvalue_reference<X>::type operator*() const throw(); 385 X* operator->() const throw(); 386 X* get() const throw(); 387 X* release() throw(); 388 void reset(X* p =0) throw(); 389 390 auto_ptr(auto_ptr_ref<X>) throw(); 391 template<class Y> operator auto_ptr_ref<Y>() throw(); 392 template<class Y> operator auto_ptr<Y>() throw(); 393}; 394 395template <class T> 396struct default_delete 397{ 398 constexpr default_delete() noexcept = default; 399 template <class U> default_delete(const default_delete<U>&) noexcept; 400 401 void operator()(T*) const noexcept; 402}; 403 404template <class T> 405struct default_delete<T[]> 406{ 407 constexpr default_delete() noexcept = default; 408 void operator()(T*) const noexcept; 409 template <class U> void operator()(U*) const = delete; 410}; 411 412template <class T, class D = default_delete<T>> 413class unique_ptr 414{ 415public: 416 typedef see below pointer; 417 typedef T element_type; 418 typedef D deleter_type; 419 420 // constructors 421 constexpr unique_ptr() noexcept; 422 explicit unique_ptr(pointer p) noexcept; 423 unique_ptr(pointer p, see below d1) noexcept; 424 unique_ptr(pointer p, see below d2) noexcept; 425 unique_ptr(unique_ptr&& u) noexcept; 426 unique_ptr(nullptr_t) noexcept : unique_ptr() { } 427 template <class U, class E> 428 unique_ptr(unique_ptr<U, E>&& u) noexcept; 429 template <class U> 430 unique_ptr(auto_ptr<U>&& u) noexcept; // removed in C++17 431 432 // destructor 433 ~unique_ptr(); 434 435 // assignment 436 unique_ptr& operator=(unique_ptr&& u) noexcept; 437 template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; 438 unique_ptr& operator=(nullptr_t) noexcept; 439 440 // observers 441 typename add_lvalue_reference<T>::type operator*() const; 442 pointer operator->() const noexcept; 443 pointer get() const noexcept; 444 deleter_type& get_deleter() noexcept; 445 const deleter_type& get_deleter() const noexcept; 446 explicit operator bool() const noexcept; 447 448 // modifiers 449 pointer release() noexcept; 450 void reset(pointer p = pointer()) noexcept; 451 void swap(unique_ptr& u) noexcept; 452}; 453 454template <class T, class D> 455class unique_ptr<T[], D> 456{ 457public: 458 typedef implementation-defined pointer; 459 typedef T element_type; 460 typedef D deleter_type; 461 462 // constructors 463 constexpr unique_ptr() noexcept; 464 explicit unique_ptr(pointer p) noexcept; 465 unique_ptr(pointer p, see below d) noexcept; 466 unique_ptr(pointer p, see below d) noexcept; 467 unique_ptr(unique_ptr&& u) noexcept; 468 unique_ptr(nullptr_t) noexcept : unique_ptr() { } 469 470 // destructor 471 ~unique_ptr(); 472 473 // assignment 474 unique_ptr& operator=(unique_ptr&& u) noexcept; 475 unique_ptr& operator=(nullptr_t) noexcept; 476 477 // observers 478 T& operator[](size_t i) const; 479 pointer get() const noexcept; 480 deleter_type& get_deleter() noexcept; 481 const deleter_type& get_deleter() const noexcept; 482 explicit operator bool() const noexcept; 483 484 // modifiers 485 pointer release() noexcept; 486 void reset(pointer p = pointer()) noexcept; 487 void reset(nullptr_t) noexcept; 488 template <class U> void reset(U) = delete; 489 void swap(unique_ptr& u) noexcept; 490}; 491 492template <class T, class D> 493 void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; 494 495template <class T1, class D1, class T2, class D2> 496 bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 497template <class T1, class D1, class T2, class D2> 498 bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 499template <class T1, class D1, class T2, class D2> 500 bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 501template <class T1, class D1, class T2, class D2> 502 bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 503template <class T1, class D1, class T2, class D2> 504 bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 505template <class T1, class D1, class T2, class D2> 506 bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); 507 508template <class T, class D> 509 bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; 510template <class T, class D> 511 bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; 512template <class T, class D> 513 bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; 514template <class T, class D> 515 bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; 516 517template <class T, class D> 518 bool operator<(const unique_ptr<T, D>& x, nullptr_t); 519template <class T, class D> 520 bool operator<(nullptr_t, const unique_ptr<T, D>& y); 521template <class T, class D> 522 bool operator<=(const unique_ptr<T, D>& x, nullptr_t); 523template <class T, class D> 524 bool operator<=(nullptr_t, const unique_ptr<T, D>& y); 525template <class T, class D> 526 bool operator>(const unique_ptr<T, D>& x, nullptr_t); 527template <class T, class D> 528 bool operator>(nullptr_t, const unique_ptr<T, D>& y); 529template <class T, class D> 530 bool operator>=(const unique_ptr<T, D>& x, nullptr_t); 531template <class T, class D> 532 bool operator>=(nullptr_t, const unique_ptr<T, D>& y); 533 534class bad_weak_ptr 535 : public std::exception 536{ 537 bad_weak_ptr() noexcept; 538}; 539 540template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args); // C++14 541template<class T> unique_ptr<T> make_unique(size_t n); // C++14 542template<class T, class... Args> unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] 543 544template<class E, class T, class Y, class D> 545 basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p); 546 547template<class T> 548class shared_ptr 549{ 550public: 551 typedef T element_type; // until C++17 552 typedef remove_extent_t<T> element_type; // since C++17 553 typedef weak_ptr<T> weak_type; // C++17 554 555 // constructors: 556 constexpr shared_ptr() noexcept; 557 template<class Y> explicit shared_ptr(Y* p); 558 template<class Y, class D> shared_ptr(Y* p, D d); 559 template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); 560 template <class D> shared_ptr(nullptr_t p, D d); 561 template <class D, class A> shared_ptr(nullptr_t p, D d, A a); 562 template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept; 563 shared_ptr(const shared_ptr& r) noexcept; 564 template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept; 565 shared_ptr(shared_ptr&& r) noexcept; 566 template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept; 567 template<class Y> explicit shared_ptr(const weak_ptr<Y>& r); 568 template<class Y> shared_ptr(auto_ptr<Y>&& r); // removed in C++17 569 template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r); 570 shared_ptr(nullptr_t) : shared_ptr() { } 571 572 // destructor: 573 ~shared_ptr(); 574 575 // assignment: 576 shared_ptr& operator=(const shared_ptr& r) noexcept; 577 template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept; 578 shared_ptr& operator=(shared_ptr&& r) noexcept; 579 template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r); 580 template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17 581 template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r); 582 583 // modifiers: 584 void swap(shared_ptr& r) noexcept; 585 void reset() noexcept; 586 template<class Y> void reset(Y* p); 587 template<class Y, class D> void reset(Y* p, D d); 588 template<class Y, class D, class A> void reset(Y* p, D d, A a); 589 590 // observers: 591 T* get() const noexcept; 592 T& operator*() const noexcept; 593 T* operator->() const noexcept; 594 long use_count() const noexcept; 595 bool unique() const noexcept; 596 explicit operator bool() const noexcept; 597 template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept; 598 template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept; 599}; 600 601template<class T> 602shared_ptr(weak_ptr<T>) -> shared_ptr<T>; 603template<class T, class D> 604shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>; 605 606// shared_ptr comparisons: 607template<class T, class U> 608 bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 609template<class T, class U> 610 bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 611template<class T, class U> 612 bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 613template<class T, class U> 614 bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 615template<class T, class U> 616 bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 617template<class T, class U> 618 bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; 619 620template <class T> 621 bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept; 622template <class T> 623 bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept; 624template <class T> 625 bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept; 626template <class T> 627 bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept; 628template <class T> 629 bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept; 630template <class T> 631bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept; 632template <class T> 633 bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept; 634template <class T> 635 bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept; 636template <class T> 637 bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept; 638template <class T> 639 bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept; 640template <class T> 641 bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept; 642template <class T> 643 bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept; 644 645// shared_ptr specialized algorithms: 646template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept; 647 648// shared_ptr casts: 649template<class T, class U> 650 shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept; 651template<class T, class U> 652 shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept; 653template<class T, class U> 654 shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept; 655 656// shared_ptr I/O: 657template<class E, class T, class Y> 658 basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p); 659 660// shared_ptr get_deleter: 661template<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept; 662 663template<class T, class... Args> 664 shared_ptr<T> make_shared(Args&&... args); 665template<class T, class A, class... Args> 666 shared_ptr<T> allocate_shared(const A& a, Args&&... args); 667 668template<class T> 669class weak_ptr 670{ 671public: 672 typedef T element_type; // until C++17 673 typedef remove_extent_t<T> element_type; // since C++17 674 675 // constructors 676 constexpr weak_ptr() noexcept; 677 template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept; 678 weak_ptr(weak_ptr const& r) noexcept; 679 template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept; 680 weak_ptr(weak_ptr&& r) noexcept; // C++14 681 template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14 682 683 // destructor 684 ~weak_ptr(); 685 686 // assignment 687 weak_ptr& operator=(weak_ptr const& r) noexcept; 688 template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept; 689 template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept; 690 weak_ptr& operator=(weak_ptr&& r) noexcept; // C++14 691 template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14 692 693 // modifiers 694 void swap(weak_ptr& r) noexcept; 695 void reset() noexcept; 696 697 // observers 698 long use_count() const noexcept; 699 bool expired() const noexcept; 700 shared_ptr<T> lock() const noexcept; 701 template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept; 702 template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept; 703}; 704 705template<class T> 706weak_ptr(shared_ptr<T>) -> weak_ptr<T>; 707 708// weak_ptr specialized algorithms: 709template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; 710 711// class owner_less: 712template<class T> struct owner_less; 713 714template<class T> 715struct owner_less<shared_ptr<T> > 716 : binary_function<shared_ptr<T>, shared_ptr<T>, bool> 717{ 718 typedef bool result_type; 719 bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept; 720 bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept; 721 bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept; 722}; 723 724template<class T> 725struct owner_less<weak_ptr<T> > 726 : binary_function<weak_ptr<T>, weak_ptr<T>, bool> 727{ 728 typedef bool result_type; 729 bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept; 730 bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept; 731 bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept; 732}; 733 734template <> // Added in C++14 735struct owner_less<void> 736{ 737 template <class _Tp, class _Up> 738 bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept; 739 template <class _Tp, class _Up> 740 bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept; 741 template <class _Tp, class _Up> 742 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept; 743 template <class _Tp, class _Up> 744 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept; 745 746 typedef void is_transparent; 747}; 748 749template<class T> 750class enable_shared_from_this 751{ 752protected: 753 constexpr enable_shared_from_this() noexcept; 754 enable_shared_from_this(enable_shared_from_this const&) noexcept; 755 enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept; 756 ~enable_shared_from_this(); 757public: 758 shared_ptr<T> shared_from_this(); 759 shared_ptr<T const> shared_from_this() const; 760}; 761 762template<class T> 763 bool atomic_is_lock_free(const shared_ptr<T>* p); 764template<class T> 765 shared_ptr<T> atomic_load(const shared_ptr<T>* p); 766template<class T> 767 shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo); 768template<class T> 769 void atomic_store(shared_ptr<T>* p, shared_ptr<T> r); 770template<class T> 771 void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); 772template<class T> 773 shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r); 774template<class T> 775 shared_ptr<T> 776 atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo); 777template<class T> 778 bool 779 atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); 780template<class T> 781 bool 782 atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w); 783template<class T> 784 bool 785 atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v, 786 shared_ptr<T> w, memory_order success, 787 memory_order failure); 788template<class T> 789 bool 790 atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v, 791 shared_ptr<T> w, memory_order success, 792 memory_order failure); 793// Hash support 794template <class T> struct hash; 795template <class T, class D> struct hash<unique_ptr<T, D> >; 796template <class T> struct hash<shared_ptr<T> >; 797 798template <class T, class Alloc> 799 inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value; 800 801void* align(size_t alignment, size_t size, void*& ptr, size_t& space); 802 803} // std 804 805*/ 806 807#include <__config> 808#include <__functional_base> 809#include <__memory/addressof.h> 810#include <__memory/allocation_guard.h> 811#include <__memory/allocator.h> 812#include <__memory/allocator_arg_t.h> 813#include <__memory/allocator_traits.h> 814#include <__memory/compressed_pair.h> 815#include <__memory/concepts.h> 816#include <__memory/construct_at.h> 817#include <__memory/pointer_traits.h> 818#include <__memory/ranges_construct_at.h> 819#include <__memory/ranges_uninitialized_algorithms.h> 820#include <__memory/raw_storage_iterator.h> 821#include <__memory/shared_ptr.h> 822#include <__memory/temporary_buffer.h> 823#include <__memory/uninitialized_algorithms.h> 824#include <__memory/unique_ptr.h> 825#include <__memory/uses_allocator.h> 826#include <compare> 827#include <cstddef> 828#include <cstdint> 829#include <cstring> 830#include <iosfwd> 831#include <iterator> 832#include <new> 833#include <stdexcept> 834#include <tuple> 835#include <type_traits> 836#include <typeinfo> 837#include <utility> 838#include <version> 839 840#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 841# include <__memory/auto_ptr.h> 842#endif 843 844#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 845#pragma GCC system_header 846#endif 847 848_LIBCPP_BEGIN_NAMESPACE_STD 849 850template <class _Alloc, class _Ptr> 851_LIBCPP_INLINE_VISIBILITY 852void __construct_forward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) { 853 static_assert(__is_cpp17_move_insertable<_Alloc>::value, 854 "The specified type does not meet the requirements of Cpp17MoveInsertable"); 855 typedef allocator_traits<_Alloc> _Traits; 856 for (; __begin1 != __end1; ++__begin1, (void)++__begin2) { 857 _Traits::construct(__a, _VSTD::__to_address(__begin2), 858#ifdef _LIBCPP_NO_EXCEPTIONS 859 _VSTD::move(*__begin1) 860#else 861 _VSTD::move_if_noexcept(*__begin1) 862#endif 863 ); 864 } 865} 866 867template <class _Alloc, class _Tp, typename enable_if< 868 (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) && 869 is_trivially_move_constructible<_Tp>::value 870>::type> 871_LIBCPP_INLINE_VISIBILITY 872void __construct_forward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) { 873 ptrdiff_t _Np = __end1 - __begin1; 874 if (_Np > 0) { 875 _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp)); 876 __begin2 += _Np; 877 } 878} 879 880template <class _Alloc, class _Iter, class _Ptr> 881_LIBCPP_INLINE_VISIBILITY 882void __construct_range_forward(_Alloc& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2) { 883 typedef allocator_traits<_Alloc> _Traits; 884 for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) { 885 _Traits::construct(__a, _VSTD::__to_address(__begin2), *__begin1); 886 } 887} 888 889template <class _Alloc, class _Source, class _Dest, 890 class _RawSource = typename remove_const<_Source>::type, 891 class _RawDest = typename remove_const<_Dest>::type, 892 class = 893 typename enable_if< 894 is_trivially_copy_constructible<_Dest>::value && 895 is_same<_RawSource, _RawDest>::value && 896 (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Dest*, _Source&>::value) 897 >::type> 898_LIBCPP_INLINE_VISIBILITY 899void __construct_range_forward(_Alloc&, _Source* __begin1, _Source* __end1, _Dest*& __begin2) { 900 ptrdiff_t _Np = __end1 - __begin1; 901 if (_Np > 0) { 902 _VSTD::memcpy(const_cast<_RawDest*>(__begin2), __begin1, _Np * sizeof(_Dest)); 903 __begin2 += _Np; 904 } 905} 906 907template <class _Alloc, class _Ptr> 908_LIBCPP_INLINE_VISIBILITY 909void __construct_backward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) { 910 static_assert(__is_cpp17_move_insertable<_Alloc>::value, 911 "The specified type does not meet the requirements of Cpp17MoveInsertable"); 912 typedef allocator_traits<_Alloc> _Traits; 913 while (__end1 != __begin1) { 914 _Traits::construct(__a, _VSTD::__to_address(__end2 - 1), 915#ifdef _LIBCPP_NO_EXCEPTIONS 916 _VSTD::move(*--__end1) 917#else 918 _VSTD::move_if_noexcept(*--__end1) 919#endif 920 ); 921 --__end2; 922 } 923} 924 925template <class _Alloc, class _Tp, class = typename enable_if< 926 (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) && 927 is_trivially_move_constructible<_Tp>::value 928>::type> 929_LIBCPP_INLINE_VISIBILITY 930void __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) { 931 ptrdiff_t _Np = __end1 - __begin1; 932 __end2 -= _Np; 933 if (_Np > 0) 934 _VSTD::memcpy(static_cast<void*>(__end2), static_cast<void const*>(__begin1), _Np * sizeof(_Tp)); 935} 936 937struct __destruct_n 938{ 939private: 940 size_t __size_; 941 942 template <class _Tp> 943 _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT 944 {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();} 945 946 template <class _Tp> 947 _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT 948 {} 949 950 _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT 951 {++__size_;} 952 _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT 953 {} 954 955 _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT 956 {__size_ = __s;} 957 _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT 958 {} 959public: 960 _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT 961 : __size_(__s) {} 962 963 template <class _Tp> 964 _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT 965 {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 966 967 template <class _Tp> 968 _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT 969 {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 970 971 template <class _Tp> 972 _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT 973 {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());} 974}; 975 976_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space); 977 978// --- Helper for container swap -- 979template <typename _Alloc> 980_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 981void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) 982#if _LIBCPP_STD_VER > 11 983 _NOEXCEPT 984#else 985 _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) 986#endif 987{ 988 using _VSTD::swap; 989 swap(__a1, __a2); 990} 991 992template <typename _Alloc> 993inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 994void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} 995 996template <typename _Alloc> 997inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 998void __swap_allocator(_Alloc & __a1, _Alloc & __a2) 999#if _LIBCPP_STD_VER > 11 1000 _NOEXCEPT 1001#else 1002 _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) 1003#endif 1004{ 1005 _VSTD::__swap_allocator(__a1, __a2, 1006 integral_constant<bool, allocator_traits<_Alloc>::propagate_on_container_swap::value>()); 1007} 1008 1009template <typename _Alloc, typename _Traits=allocator_traits<_Alloc> > 1010struct __noexcept_move_assign_container : public integral_constant<bool, 1011 _Traits::propagate_on_container_move_assignment::value 1012#if _LIBCPP_STD_VER > 14 1013 || _Traits::is_always_equal::value 1014#else 1015 && is_nothrow_move_assignable<_Alloc>::value 1016#endif 1017 > {}; 1018 1019 1020template <class _Tp, class _Alloc> 1021struct __temp_value { 1022 typedef allocator_traits<_Alloc> _Traits; 1023 1024 typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v; 1025 _Alloc &__a; 1026 1027 _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } 1028 _Tp & get() { return *__addr(); } 1029 1030 template<class... _Args> 1031 _LIBCPP_NO_CFI 1032 __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) { 1033 _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)), 1034 _VSTD::forward<_Args>(__args)...); 1035 } 1036 1037 ~__temp_value() { _Traits::destroy(__a, __addr()); } 1038 }; 1039 1040template<typename _Alloc, typename = void, typename = void> 1041struct __is_allocator : false_type {}; 1042 1043template<typename _Alloc> 1044struct __is_allocator<_Alloc, 1045 typename __void_t<typename _Alloc::value_type>::type, 1046 typename __void_t<decltype(declval<_Alloc&>().allocate(size_t(0)))>::type 1047 > 1048 : true_type {}; 1049 1050// __builtin_new_allocator -- A non-templated helper for allocating and 1051// deallocating memory using __builtin_operator_new and 1052// __builtin_operator_delete. It should be used in preference to 1053// `std::allocator<T>` to avoid additional instantiations. 1054struct __builtin_new_allocator { 1055 struct __builtin_new_deleter { 1056 typedef void* pointer_type; 1057 1058 _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align) 1059 : __size_(__size), __align_(__align) {} 1060 1061 void operator()(void* p) const _NOEXCEPT { 1062 _VSTD::__libcpp_deallocate(p, __size_, __align_); 1063 } 1064 1065 private: 1066 size_t __size_; 1067 size_t __align_; 1068 }; 1069 1070 typedef unique_ptr<void, __builtin_new_deleter> __holder_t; 1071 1072 static __holder_t __allocate_bytes(size_t __s, size_t __align) { 1073 return __holder_t(_VSTD::__libcpp_allocate(__s, __align), 1074 __builtin_new_deleter(__s, __align)); 1075 } 1076 1077 static void __deallocate_bytes(void* __p, size_t __s, 1078 size_t __align) _NOEXCEPT { 1079 _VSTD::__libcpp_deallocate(__p, __s, __align); 1080 } 1081 1082 template <class _Tp> 1083 _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE 1084 static __holder_t __allocate_type(size_t __n) { 1085 return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); 1086 } 1087 1088 template <class _Tp> 1089 _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE 1090 static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT { 1091 __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); 1092 } 1093}; 1094 1095 1096_LIBCPP_END_NAMESPACE_STD 1097 1098#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 1099# include <__pstl_memory> 1100#endif 1101 1102#endif // _LIBCPP_MEMORY 1103