Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/bits/alloc_traits.h
$ cat -n /usr/include/c++/13/bits/alloc_traits.h 1 // Allocator traits -*- C++ -*- 2 3 // Copyright (C) 2011-2023 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 //
. 24 25 /** @file bits/alloc_traits.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{memory} 28 */ 29 30 #ifndef _ALLOC_TRAITS_H 31 #define _ALLOC_TRAITS_H 1 32 33 #include
34 #include
35 #if __cplusplus >= 201103L 36 # include
37 # include
38 # if _GLIBCXX_HOSTED 39 # include
40 # endif 41 #endif 42 43 namespace std _GLIBCXX_VISIBILITY(default) 44 { 45 _GLIBCXX_BEGIN_NAMESPACE_VERSION 46 47 #if __cplusplus >= 201103L 48 #define __cpp_lib_allocator_traits_is_always_equal 201411L 49 50 /// @cond undocumented 51 struct __allocator_traits_base 52 { 53 template
54 struct __rebind : __replace_first_arg<_Tp, _Up> 55 { 56 static_assert(is_same< 57 typename __replace_first_arg<_Tp, typename _Tp::value_type>::type, 58 _Tp>::value, 59 "allocator_traits
::rebind_alloc
must be A"); 60 }; 61 62 template
63 struct __rebind<_Tp, _Up, 64 __void_t
::other>> 65 { 66 using type = typename _Tp::template rebind<_Up>::other; 67 68 static_assert(is_same< 69 typename _Tp::template rebind
::other, 70 _Tp>::value, 71 "allocator_traits
::rebind_alloc
must be A"); 72 }; 73 74 protected: 75 template
76 using __pointer = typename _Tp::pointer; 77 template
78 using __c_pointer = typename _Tp::const_pointer; 79 template
80 using __v_pointer = typename _Tp::void_pointer; 81 template
82 using __cv_pointer = typename _Tp::const_void_pointer; 83 template
84 using __pocca = typename _Tp::propagate_on_container_copy_assignment; 85 template
86 using __pocma = typename _Tp::propagate_on_container_move_assignment; 87 template
88 using __pocs = typename _Tp::propagate_on_container_swap; 89 template
90 using __equal = __type_identity
; 91 }; 92 93 template
94 using __alloc_rebind 95 = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type; 96 /// @endcond 97 98 /** 99 * @brief Uniform interface to all allocator types. 100 * @headerfile memory 101 * @ingroup allocators 102 * @since C++11 103 */ 104 template
105 struct allocator_traits : __allocator_traits_base 106 { 107 /// The allocator type 108 typedef _Alloc allocator_type; 109 /// The allocated type 110 typedef typename _Alloc::value_type value_type; 111 112 /** 113 * @brief The allocator's pointer type. 114 * 115 * @c Alloc::pointer if that type exists, otherwise @c value_type* 116 */ 117 using pointer = __detected_or_t
; 118 119 private: 120 // Select _Func<_Alloc> or pointer_traits
::rebind<_Tp> 121 template
class _Func, typename _Tp, typename = void> 122 struct _Ptr 123 { 124 using type = typename pointer_traits
::template rebind<_Tp>; 125 }; 126 127 template
class _Func, typename _Tp> 128 struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>> 129 { 130 using type = _Func<_Alloc>; 131 }; 132 133 // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type 134 template
135 struct _Diff 136 { using type = typename pointer_traits<_PtrT>::difference_type; }; 137 138 template
139 struct _Diff<_A2, _PtrT, __void_t
> 140 { using type = typename _A2::difference_type; }; 141 142 // Select _A2::size_type or make_unsigned<_DiffT>::type 143 template
144 struct _Size : make_unsigned<_DiffT> { }; 145 146 template
147 struct _Size<_A2, _DiffT, __void_t
> 148 { using type = typename _A2::size_type; }; 149 150 public: 151 /** 152 * @brief The allocator's const pointer type. 153 * 154 * @c Alloc::const_pointer if that type exists, otherwise 155 *
pointer_traits
::rebind
156 */ 157 using const_pointer = typename _Ptr<__c_pointer, const value_type>::type; 158 159 /** 160 * @brief The allocator's void pointer type. 161 * 162 * @c Alloc::void_pointer if that type exists, otherwise 163 *
pointer_traits
::rebind
164 */ 165 using void_pointer = typename _Ptr<__v_pointer, void>::type; 166 167 /** 168 * @brief The allocator's const void pointer type. 169 * 170 * @c Alloc::const_void_pointer if that type exists, otherwise 171 *
pointer_traits
::rebind
172 */ 173 using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type; 174 175 /** 176 * @brief The allocator's difference type 177 * 178 * @c Alloc::difference_type if that type exists, otherwise 179 *
pointer_traits
::difference_type
180 */ 181 using difference_type = typename _Diff<_Alloc, pointer>::type; 182 183 /** 184 * @brief The allocator's size type 185 * 186 * @c Alloc::size_type if that type exists, otherwise 187 *
make_unsigned
::type
188 */ 189 using size_type = typename _Size<_Alloc, difference_type>::type; 190 191 /** 192 * @brief How the allocator is propagated on copy assignment 193 * 194 * @c Alloc::propagate_on_container_copy_assignment if that type exists, 195 * otherwise @c false_type 196 */ 197 using propagate_on_container_copy_assignment 198 = __detected_or_t
; 199 200 /** 201 * @brief How the allocator is propagated on move assignment 202 * 203 * @c Alloc::propagate_on_container_move_assignment if that type exists, 204 * otherwise @c false_type 205 */ 206 using propagate_on_container_move_assignment 207 = __detected_or_t
; 208 209 /** 210 * @brief How the allocator is propagated on swap 211 * 212 * @c Alloc::propagate_on_container_swap if that type exists, 213 * otherwise @c false_type 214 */ 215 using propagate_on_container_swap 216 = __detected_or_t
; 217 218 /** 219 * @brief Whether all instances of the allocator type compare equal. 220 * 221 * @c Alloc::is_always_equal if that type exists, 222 * otherwise @c is_empty
::type 223 */ 224 using is_always_equal 225 = typename __detected_or_t
, __equal, _Alloc>::type; 226 227 template
228 using rebind_alloc = __alloc_rebind<_Alloc, _Tp>; 229 template
230 using rebind_traits = allocator_traits
>; 231 232 private: 233 template
234 static constexpr auto 235 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int) 236 -> decltype(__a.allocate(__n, __hint)) 237 { return __a.allocate(__n, __hint); } 238 239 template
240 static constexpr pointer 241 _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...) 242 { return __a.allocate(__n); } 243 244 template
245 struct __construct_helper 246 { 247 template
()->construct( 249 std::declval<_Tp*>(), std::declval<_Args>()...))> 250 static true_type __test(int); 251 252 template
253 static false_type __test(...); 254 255 using type = decltype(__test<_Alloc>(0)); 256 }; 257 258 template
259 using __has_construct 260 = typename __construct_helper<_Tp, _Args...>::type; 261 262 template
263 static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>> 264 _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) 265 noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...))) 266 { __a.construct(__p, std::forward<_Args>(__args)...); } 267 268 template
269 static _GLIBCXX14_CONSTEXPR 270 _Require<__and_<__not_<__has_construct<_Tp, _Args...>>, 271 is_constructible<_Tp, _Args...>>> 272 _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) 273 noexcept(std::is_nothrow_constructible<_Tp, _Args...>::value) 274 { 275 #if __cplusplus <= 201703L 276 ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); 277 #else 278 std::construct_at(__p, std::forward<_Args>(__args)...); 279 #endif 280 } 281 282 template
283 static _GLIBCXX14_CONSTEXPR auto 284 _S_destroy(_Alloc2& __a, _Tp* __p, int) 285 noexcept(noexcept(__a.destroy(__p))) 286 -> decltype(__a.destroy(__p)) 287 { __a.destroy(__p); } 288 289 template
290 static _GLIBCXX14_CONSTEXPR void 291 _S_destroy(_Alloc2&, _Tp* __p, ...) 292 noexcept(std::is_nothrow_destructible<_Tp>::value) 293 { std::_Destroy(__p); } 294 295 template
296 static constexpr auto 297 _S_max_size(_Alloc2& __a, int) 298 -> decltype(__a.max_size()) 299 { return __a.max_size(); } 300 301 template
302 static constexpr size_type 303 _S_max_size(_Alloc2&, ...) 304 { 305 // _GLIBCXX_RESOLVE_LIB_DEFECTS 306 // 2466. allocator_traits::max_size() default behavior is incorrect 307 return __gnu_cxx::__numeric_traits
::__max 308 / sizeof(value_type); 309 } 310 311 template
312 static constexpr auto 313 _S_select(_Alloc2& __a, int) 314 -> decltype(__a.select_on_container_copy_construction()) 315 { return __a.select_on_container_copy_construction(); } 316 317 template
318 static constexpr _Alloc2 319 _S_select(_Alloc2& __a, ...) 320 { return __a; } 321 322 public: 323 324 /** 325 * @brief Allocate memory. 326 * @param __a An allocator. 327 * @param __n The number of objects to allocate space for. 328 * 329 * Calls @c a.allocate(n) 330 */ 331 _GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer 332 allocate(_Alloc& __a, size_type __n) 333 { return __a.allocate(__n); } 334 335 /** 336 * @brief Allocate memory. 337 * @param __a An allocator. 338 * @param __n The number of objects to allocate space for. 339 * @param __hint Aid to locality. 340 * @return Memory of suitable size and alignment for @a n objects 341 * of type @c value_type 342 * 343 * Returns
a.allocate(n, hint)
if that expression is 344 * well-formed, otherwise returns @c a.allocate(n) 345 */ 346 _GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer 347 allocate(_Alloc& __a, size_type __n, const_void_pointer __hint) 348 { return _S_allocate(__a, __n, __hint, 0); } 349 350 /** 351 * @brief Deallocate memory. 352 * @param __a An allocator. 353 * @param __p Pointer to the memory to deallocate. 354 * @param __n The number of objects space was allocated for. 355 * 356 * Calls
a.deallocate(p, n)
357 */ 358 static _GLIBCXX20_CONSTEXPR void 359 deallocate(_Alloc& __a, pointer __p, size_type __n) 360 { __a.deallocate(__p, __n); } 361 362 /** 363 * @brief Construct an object of type `_Tp` 364 * @param __a An allocator. 365 * @param __p Pointer to memory of suitable size and alignment for Tp 366 * @param __args Constructor arguments. 367 * 368 * Calls
__a.construct(__p, std::forward
(__args)...)
369 * if that expression is well-formed, otherwise uses placement-new 370 * to construct an object of type @a _Tp at location @a __p from the 371 * arguments @a __args... 372 */ 373 template
374 static _GLIBCXX20_CONSTEXPR auto 375 construct(_Alloc& __a, _Tp* __p, _Args&&... __args) 376 noexcept(noexcept(_S_construct(__a, __p, 377 std::forward<_Args>(__args)...))) 378 -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...)) 379 { _S_construct(__a, __p, std::forward<_Args>(__args)...); } 380 381 /** 382 * @brief Destroy an object of type @a _Tp 383 * @param __a An allocator. 384 * @param __p Pointer to the object to destroy 385 * 386 * Calls @c __a.destroy(__p) if that expression is well-formed, 387 * otherwise calls @c __p->~_Tp() 388 */ 389 template
390 static _GLIBCXX20_CONSTEXPR void 391 destroy(_Alloc& __a, _Tp* __p) 392 noexcept(noexcept(_S_destroy(__a, __p, 0))) 393 { _S_destroy(__a, __p, 0); } 394 395 /** 396 * @brief The maximum supported allocation size 397 * @param __a An allocator. 398 * @return @c __a.max_size() or @c numeric_limits
::max() 399 * 400 * Returns @c __a.max_size() if that expression is well-formed, 401 * otherwise returns @c numeric_limits
::max() 402 */ 403 static _GLIBCXX20_CONSTEXPR size_type 404 max_size(const _Alloc& __a) noexcept 405 { return _S_max_size(__a, 0); } 406 407 /** 408 * @brief Obtain an allocator to use when copying a container. 409 * @param __rhs An allocator. 410 * @return @c __rhs.select_on_container_copy_construction() or @a __rhs 411 * 412 * Returns @c __rhs.select_on_container_copy_construction() if that 413 * expression is well-formed, otherwise returns @a __rhs 414 */ 415 static _GLIBCXX20_CONSTEXPR _Alloc 416 select_on_container_copy_construction(const _Alloc& __rhs) 417 { return _S_select(__rhs, 0); } 418 }; 419 420 #if _GLIBCXX_HOSTED 421 422 #if __cplusplus > 201703L 423 # define __cpp_lib_constexpr_dynamic_alloc 201907L 424 #endif 425 426 /// Partial specialization for std::allocator. 427 template
428 struct allocator_traits
> 429 { 430 /// The allocator type 431 using allocator_type = allocator<_Tp>; 432 433 /// The allocated type 434 using value_type = _Tp; 435 436 /// The allocator's pointer type. 437 using pointer = _Tp*; 438 439 /// The allocator's const pointer type. 440 using const_pointer = const _Tp*; 441 442 /// The allocator's void pointer type. 443 using void_pointer = void*; 444 445 /// The allocator's const void pointer type. 446 using const_void_pointer = const void*; 447 448 /// The allocator's difference type 449 using difference_type = std::ptrdiff_t; 450 451 /// The allocator's size type 452 using size_type = std::size_t; 453 454 /// How the allocator is propagated on copy assignment 455 using propagate_on_container_copy_assignment = false_type; 456 457 /// How the allocator is propagated on move assignment 458 using propagate_on_container_move_assignment = true_type; 459 460 /// How the allocator is propagated on swap 461 using propagate_on_container_swap = false_type; 462 463 /// Whether all instances of the allocator type compare equal. 464 using is_always_equal = true_type; 465 466 template
467 using rebind_alloc = allocator<_Up>; 468 469 template
470 using rebind_traits = allocator_traits
>; 471 472 /** 473 * @brief Allocate memory. 474 * @param __a An allocator. 475 * @param __n The number of objects to allocate space for. 476 * 477 * Calls @c a.allocate(n) 478 */ 479 [[__nodiscard__,__gnu__::__always_inline__]] 480 static _GLIBCXX20_CONSTEXPR pointer 481 allocate(allocator_type& __a, size_type __n) 482 { return __a.allocate(__n); } 483 484 /** 485 * @brief Allocate memory. 486 * @param __a An allocator. 487 * @param __n The number of objects to allocate space for. 488 * @param __hint Aid to locality. 489 * @return Memory of suitable size and alignment for @a n objects 490 * of type @c value_type 491 * 492 * Returns
a.allocate(n, hint)
493 */ 494 [[__nodiscard__,__gnu__::__always_inline__]] 495 static _GLIBCXX20_CONSTEXPR pointer 496 allocate(allocator_type& __a, size_type __n, 497 [[maybe_unused]] const_void_pointer __hint) 498 { 499 #if __cplusplus <= 201703L 500 return __a.allocate(__n, __hint); 501 #else 502 return __a.allocate(__n); 503 #endif 504 } 505 506 /** 507 * @brief Deallocate memory. 508 * @param __a An allocator. 509 * @param __p Pointer to the memory to deallocate. 510 * @param __n The number of objects space was allocated for. 511 * 512 * Calls
a.deallocate(p, n)
513 */ 514 [[__gnu__::__always_inline__]] 515 static _GLIBCXX20_CONSTEXPR void 516 deallocate(allocator_type& __a, pointer __p, size_type __n) 517 { __a.deallocate(__p, __n); } 518 519 /** 520 * @brief Construct an object of type `_Up` 521 * @param __a An allocator. 522 * @param __p Pointer to memory of suitable size and alignment for 523 * an object of type `_Up`. 524 * @param __args Constructor arguments. 525 * 526 * Calls `__a.construct(__p, std::forward<_Args>(__args)...)` 527 * in C++11, C++14 and C++17. Changed in C++20 to call 528 * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead. 529 */ 530 template
531 [[__gnu__::__always_inline__]] 532 static _GLIBCXX20_CONSTEXPR void 533 construct(allocator_type& __a __attribute__((__unused__)), _Up* __p, 534 _Args&&... __args) 535 noexcept(std::is_nothrow_constructible<_Up, _Args...>::value) 536 { 537 #if __cplusplus <= 201703L 538 __a.construct(__p, std::forward<_Args>(__args)...); 539 #else 540 std::construct_at(__p, std::forward<_Args>(__args)...); 541 #endif 542 } 543 544 /** 545 * @brief Destroy an object of type @a _Up 546 * @param __a An allocator. 547 * @param __p Pointer to the object to destroy 548 * 549 * Calls @c __a.destroy(__p). 550 */ 551 template
552 [[__gnu__::__always_inline__]] 553 static _GLIBCXX20_CONSTEXPR void 554 destroy(allocator_type& __a __attribute__((__unused__)), _Up* __p) 555 noexcept(is_nothrow_destructible<_Up>::value) 556 { 557 #if __cplusplus <= 201703L 558 __a.destroy(__p); 559 #else 560 std::destroy_at(__p); 561 #endif 562 } 563 564 /** 565 * @brief The maximum supported allocation size 566 * @param __a An allocator. 567 * @return @c __a.max_size() 568 */ 569 [[__gnu__::__always_inline__]] 570 static _GLIBCXX20_CONSTEXPR size_type 571 max_size(const allocator_type& __a __attribute__((__unused__))) noexcept 572 { 573 #if __cplusplus <= 201703L 574 return __a.max_size(); 575 #else 576 return size_t(-1) / sizeof(value_type); 577 #endif 578 } 579 580 /** 581 * @brief Obtain an allocator to use when copying a container. 582 * @param __rhs An allocator. 583 * @return @c __rhs 584 */ 585 [[__gnu__::__always_inline__]] 586 static _GLIBCXX20_CONSTEXPR allocator_type 587 select_on_container_copy_construction(const allocator_type& __rhs) 588 { return __rhs; } 589 }; 590 591 /// Explicit specialization for std::allocator
. 592 template<> 593 struct allocator_traits
> 594 { 595 /// The allocator type 596 using allocator_type = allocator
; 597 598 /// The allocated type 599 using value_type = void; 600 601 /// The allocator's pointer type. 602 using pointer = void*; 603 604 /// The allocator's const pointer type. 605 using const_pointer = const void*; 606 607 /// The allocator's void pointer type. 608 using void_pointer = void*; 609 610 /// The allocator's const void pointer type. 611 using const_void_pointer = const void*; 612 613 /// The allocator's difference type 614 using difference_type = std::ptrdiff_t; 615 616 /// The allocator's size type 617 using size_type = std::size_t; 618 619 /// How the allocator is propagated on copy assignment 620 using propagate_on_container_copy_assignment = false_type; 621 622 /// How the allocator is propagated on move assignment 623 using propagate_on_container_move_assignment = true_type; 624 625 /// How the allocator is propagated on swap 626 using propagate_on_container_swap = false_type; 627 628 /// Whether all instances of the allocator type compare equal. 629 using is_always_equal = true_type; 630 631 template
632 using rebind_alloc = allocator<_Up>; 633 634 template
635 using rebind_traits = allocator_traits
>; 636 637 /// allocate is ill-formed for allocator
638 static void* 639 allocate(allocator_type&, size_type, const void* = nullptr) = delete; 640 641 /// deallocate is ill-formed for allocator
642 static void 643 deallocate(allocator_type&, void*, size_type) = delete; 644 645 /** 646 * @brief Construct an object of type `_Up` 647 * @param __a An allocator. 648 * @param __p Pointer to memory of suitable size and alignment for 649 * an object of type `_Up`. 650 * @param __args Constructor arguments. 651 * 652 * Calls `__a.construct(__p, std::forward<_Args>(__args)...)` 653 * in C++11, C++14 and C++17. Changed in C++20 to call 654 * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead. 655 */ 656 template
657 [[__gnu__::__always_inline__]] 658 static _GLIBCXX20_CONSTEXPR void 659 construct(allocator_type&, _Up* __p, _Args&&... __args) 660 noexcept(std::is_nothrow_constructible<_Up, _Args...>::value) 661 { std::_Construct(__p, std::forward<_Args>(__args)...); } 662 663 /** 664 * @brief Destroy an object of type `_Up` 665 * @param __a An allocator. 666 * @param __p Pointer to the object to destroy 667 * 668 * Invokes the destructor for `*__p`. 669 */ 670 template
671 [[__gnu__::__always_inline__]] 672 static _GLIBCXX20_CONSTEXPR void 673 destroy(allocator_type&, _Up* __p) 674 noexcept(is_nothrow_destructible<_Up>::value) 675 { std::_Destroy(__p); } 676 677 /// max_size is ill-formed for allocator
678 static size_type 679 max_size(const allocator_type&) = delete; 680 681 /** 682 * @brief Obtain an allocator to use when copying a container. 683 * @param __rhs An allocator. 684 * @return `__rhs` 685 */ 686 [[__gnu__::__always_inline__]] 687 static _GLIBCXX20_CONSTEXPR allocator_type 688 select_on_container_copy_construction(const allocator_type& __rhs) 689 { return __rhs; } 690 }; 691 #endif 692 693 /// @cond undocumented 694 #if __cplusplus < 201703L 695 template
696 [[__gnu__::__always_inline__]] 697 inline void 698 __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type) 699 { __one = __two; } 700 701 template
702 [[__gnu__::__always_inline__]] 703 inline void 704 __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type) 705 { } 706 #endif 707 708 template
709 [[__gnu__::__always_inline__]] 710 _GLIBCXX14_CONSTEXPR inline void 711 __alloc_on_copy(_Alloc& __one, const _Alloc& __two) 712 { 713 using __traits = allocator_traits<_Alloc>; 714 using __pocca = 715 typename __traits::propagate_on_container_copy_assignment::type; 716 #if __cplusplus >= 201703L 717 if constexpr (__pocca::value) 718 __one = __two; 719 #else 720 __do_alloc_on_copy(__one, __two, __pocca()); 721 #endif 722 } 723 724 template
725 [[__gnu__::__always_inline__]] 726 constexpr _Alloc 727 __alloc_on_copy(const _Alloc& __a) 728 { 729 typedef allocator_traits<_Alloc> __traits; 730 return __traits::select_on_container_copy_construction(__a); 731 } 732 733 #if __cplusplus < 201703L 734 template
735 [[__gnu__::__always_inline__]] 736 inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type) 737 { __one = std::move(__two); } 738 739 template
740 [[__gnu__::__always_inline__]] 741 inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type) 742 { } 743 #endif 744 745 template
746 [[__gnu__::__always_inline__]] 747 _GLIBCXX14_CONSTEXPR inline void 748 __alloc_on_move(_Alloc& __one, _Alloc& __two) 749 { 750 using __traits = allocator_traits<_Alloc>; 751 using __pocma 752 = typename __traits::propagate_on_container_move_assignment::type; 753 #if __cplusplus >= 201703L 754 if constexpr (__pocma::value) 755 __one = std::move(__two); 756 #else 757 __do_alloc_on_move(__one, __two, __pocma()); 758 #endif 759 } 760 761 #if __cplusplus < 201703L 762 template
763 [[__gnu__::__always_inline__]] 764 inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type) 765 { 766 using std::swap; 767 swap(__one, __two); 768 } 769 770 template
771 [[__gnu__::__always_inline__]] 772 inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type) 773 { } 774 #endif 775 776 template
777 [[__gnu__::__always_inline__]] 778 _GLIBCXX14_CONSTEXPR inline void 779 __alloc_on_swap(_Alloc& __one, _Alloc& __two) 780 { 781 using __traits = allocator_traits<_Alloc>; 782 using __pocs = typename __traits::propagate_on_container_swap::type; 783 #if __cplusplus >= 201703L 784 if constexpr (__pocs::value) 785 { 786 using std::swap; 787 swap(__one, __two); 788 } 789 #else 790 __do_alloc_on_swap(__one, __two, __pocs()); 791 #endif 792 } 793 794 template
, 796 typename = void> 797 struct __is_alloc_insertable_impl 798 : false_type 799 { }; 800 801 template
802 struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT, 803 __void_t
::construct( 804 std::declval<_Alloc&>(), std::declval<_ValueT*>(), 805 std::declval<_Tp>()))>> 806 : true_type 807 { }; 808 809 // true if _Alloc::value_type is CopyInsertable into containers using _Alloc 810 // (might be wrong if _Alloc::construct exists but is not constrained, 811 // i.e. actually trying to use it would still be invalid. Use with caution.) 812 template
813 struct __is_copy_insertable 814 : __is_alloc_insertable_impl<_Alloc, 815 typename _Alloc::value_type const&>::type 816 { }; 817 818 #if _GLIBCXX_HOSTED 819 // std::allocator<_Tp> just requires CopyConstructible 820 template
821 struct __is_copy_insertable
> 822 : is_copy_constructible<_Tp> 823 { }; 824 #endif 825 826 // true if _Alloc::value_type is MoveInsertable into containers using _Alloc 827 // (might be wrong if _Alloc::construct exists but is not constrained, 828 // i.e. actually trying to use it would still be invalid. Use with caution.) 829 template
830 struct __is_move_insertable 831 : __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type 832 { }; 833 834 #if _GLIBCXX_HOSTED 835 // std::allocator<_Tp> just requires MoveConstructible 836 template
837 struct __is_move_insertable
> 838 : is_move_constructible<_Tp> 839 { }; 840 #endif 841 842 // Trait to detect Allocator-like types. 843 template
844 struct __is_allocator : false_type { }; 845 846 template
847 struct __is_allocator<_Alloc, 848 __void_t
().allocate(size_t{}))>> 850 : true_type { }; 851 852 template
853 using _RequireAllocator 854 = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type; 855 856 template
857 using _RequireNotAllocator 858 = typename enable_if::value, _Alloc>::type; 859 860 #if __cpp_concepts >= 201907L 861 template
862 concept __allocator_like = requires (_Alloc& __a) { 863 typename _Alloc::value_type; 864 __a.deallocate(__a.allocate(1u), 1u); 865 }; 866 #endif 867 /// @endcond 868 #endif // C++11 869 870 /// @cond undocumented 871 872 // To implement Option 3 of DR 431. 873 template
874 struct __alloc_swap 875 { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } }; 876 877 template
878 struct __alloc_swap<_Alloc, false> 879 { 880 static void 881 _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT 882 { 883 // Precondition: swappable allocators. 884 if (__one != __two) 885 swap(__one, __two); 886 } 887 }; 888 889 #if __cplusplus >= 201103L 890 template
, 892 is_nothrow_move_constructible
>::value> 893 struct __shrink_to_fit_aux 894 { static bool _S_do_it(_Tp&) noexcept { return false; } }; 895 896 template
897 struct __shrink_to_fit_aux<_Tp, true> 898 { 899 _GLIBCXX20_CONSTEXPR 900 static bool 901 _S_do_it(_Tp& __c) noexcept 902 { 903 #if __cpp_exceptions 904 try 905 { 906 _Tp(__make_move_if_noexcept_iterator(__c.begin()), 907 __make_move_if_noexcept_iterator(__c.end()), 908 __c.get_allocator()).swap(__c); 909 return true; 910 } 911 catch(...) 912 { return false; } 913 #else 914 return false; 915 #endif 916 } 917 }; 918 #endif 919 920 /** 921 * Destroy a range of objects using the supplied allocator. For 922 * non-default allocators we do not optimize away invocation of 923 * destroy() even if _Tp has a trivial destructor. 924 */ 925 926 template
927 _GLIBCXX20_CONSTEXPR 928 void 929 _Destroy(_ForwardIterator __first, _ForwardIterator __last, 930 _Allocator& __alloc) 931 { 932 for (; __first != __last; ++__first) 933 #if __cplusplus < 201103L 934 __alloc.destroy(std::__addressof(*__first)); 935 #else 936 allocator_traits<_Allocator>::destroy(__alloc, 937 std::__addressof(*__first)); 938 #endif 939 } 940 941 #if _GLIBCXX_HOSTED 942 template
943 __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR 944 inline void 945 _Destroy(_ForwardIterator __first, _ForwardIterator __last, 946 allocator<_Tp>&) 947 { 948 std::_Destroy(__first, __last); 949 } 950 #endif 951 /// @endcond 952 953 _GLIBCXX_END_NAMESPACE_VERSION 954 } // namespace std 955 #endif // _ALLOC_TRAITS_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™