comparison libstdc++-v3/include/ext/bitmap_allocator.h @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 // Bitmap Allocator. -*- C++ -*- 1 // Bitmap Allocator. -*- C++ -*-
2 2
3 // Copyright (C) 2004-2018 Free Software Foundation, Inc. 3 // Copyright (C) 2004-2020 Free Software Foundation, Inc.
4 // 4 //
5 // This file is part of the GNU ISO C++ Library. This library is free 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 6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the 7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option) 8 // Free Software Foundation; either version 3, or (at your option)
43 #define _BALLOC_ALIGN_BYTES 8 43 #define _BALLOC_ALIGN_BYTES 8
44 44
45 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 45 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
46 { 46 {
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION 47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48
49 using std::size_t;
50 using std::ptrdiff_t;
51 48
52 namespace __detail 49 namespace __detail
53 { 50 {
54 /** @class __mini_vector bitmap_allocator.h bitmap_allocator.h 51 /** @class __mini_vector bitmap_allocator.h bitmap_allocator.h
55 * 52 *
75 public: 72 public:
76 typedef _Tp value_type; 73 typedef _Tp value_type;
77 typedef _Tp* pointer; 74 typedef _Tp* pointer;
78 typedef _Tp& reference; 75 typedef _Tp& reference;
79 typedef const _Tp& const_reference; 76 typedef const _Tp& const_reference;
80 typedef size_t size_type; 77 typedef std::size_t size_type;
81 typedef ptrdiff_t difference_type; 78 typedef std::ptrdiff_t difference_type;
82 typedef pointer iterator; 79 typedef pointer iterator;
83 80
84 private: 81 private:
85 pointer _M_start; 82 pointer _M_start;
86 pointer _M_finish; 83 pointer _M_finish;
88 85
89 size_type 86 size_type
90 _M_space_left() const throw() 87 _M_space_left() const throw()
91 { return _M_end_of_storage - _M_finish; } 88 { return _M_end_of_storage - _M_finish; }
92 89
93 pointer 90 _GLIBCXX_NODISCARD pointer
94 allocate(size_type __n) 91 allocate(size_type __n)
95 { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); } 92 { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); }
96 93
97 void 94 void
98 deallocate(pointer __p, size_type) 95 deallocate(pointer __p, size_type)
221 218
222 template<typename _Tp> 219 template<typename _Tp>
223 struct __mv_iter_traits<_Tp*> 220 struct __mv_iter_traits<_Tp*>
224 { 221 {
225 typedef _Tp value_type; 222 typedef _Tp value_type;
226 typedef ptrdiff_t difference_type; 223 typedef std::ptrdiff_t difference_type;
227 }; 224 };
228 225
229 enum 226 enum
230 { 227 {
231 bits_per_byte = 8, 228 bits_per_byte = 8,
232 bits_per_block = sizeof(size_t) * size_t(bits_per_byte) 229 bits_per_block = sizeof(std::size_t) * std::size_t(bits_per_byte)
233 }; 230 };
234 231
235 template<typename _ForwardIterator, typename _Tp, typename _Compare> 232 template<typename _ForwardIterator, typename _Tp, typename _Compare>
236 _ForwardIterator 233 _ForwardIterator
237 __lower_bound(_ForwardIterator __first, _ForwardIterator __last, 234 __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
263 260
264 /** @brief The number of Blocks pointed to by the address pair 261 /** @brief The number of Blocks pointed to by the address pair
265 * passed to the function. 262 * passed to the function.
266 */ 263 */
267 template<typename _AddrPair> 264 template<typename _AddrPair>
268 inline size_t 265 inline std::size_t
269 __num_blocks(_AddrPair __ap) 266 __num_blocks(_AddrPair __ap)
270 { return (__ap.second - __ap.first) + 1; } 267 { return (__ap.second - __ap.first) + 1; }
271 268
272 /** @brief The number of Bit-maps pointed to by the address pair 269 /** @brief The number of Bit-maps pointed to by the address pair
273 * passed to the function. 270 * passed to the function.
274 */ 271 */
275 template<typename _AddrPair> 272 template<typename _AddrPair>
276 inline size_t 273 inline std::size_t
277 __num_bitmaps(_AddrPair __ap) 274 __num_bitmaps(_AddrPair __ap)
278 { return __num_blocks(__ap) / size_t(bits_per_block); } 275 { return __num_blocks(__ap) / std::size_t(bits_per_block); }
279 276
280 // _Tp should be a pointer type. 277 // _Tp should be a pointer type.
281 template<typename _Tp> 278 template<typename _Tp>
282 class _Inclusive_between 279 class _Inclusive_between
283 : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> 280 : public std::unary_function<typename std::pair<_Tp, _Tp>, bool>
334 { 331 {
335 typedef typename std::pair<_Tp, _Tp> _Block_pair; 332 typedef typename std::pair<_Tp, _Tp> _Block_pair;
336 typedef typename __detail::__mini_vector<_Block_pair> _BPVector; 333 typedef typename __detail::__mini_vector<_Block_pair> _BPVector;
337 typedef typename _BPVector::difference_type _Counter_type; 334 typedef typename _BPVector::difference_type _Counter_type;
338 335
339 size_t* _M_pbitmap; 336 std::size_t* _M_pbitmap;
340 _Counter_type _M_data_offset; 337 _Counter_type _M_data_offset;
341 338
342 public: 339 public:
343 _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0) 340 _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0)
344 { } 341 { }
345 342
346 bool 343 bool
347 operator()(_Block_pair __bp) throw() 344 operator()(_Block_pair __bp) throw()
348 { 345 {
346 using std::size_t;
349 // Set the _rover to the last physical location bitmap, 347 // Set the _rover to the last physical location bitmap,
350 // which is the bitmap which belongs to the first free 348 // which is the bitmap which belongs to the first free
351 // block. Thus, the bitmaps are in exact reverse order of 349 // block. Thus, the bitmaps are in exact reverse order of
352 // the actual memory layout. So, we count down the bitmaps, 350 // the actual memory layout. So, we count down the bitmaps,
353 // which is the same as moving up the memory. 351 // which is the same as moving up the memory.
375 --__rover; 373 --__rover;
376 } 374 }
377 return false; 375 return false;
378 } 376 }
379 377
380 size_t* 378 std::size_t*
381 _M_get() const throw() 379 _M_get() const throw()
382 { return _M_pbitmap; } 380 { return _M_pbitmap; }
383 381
384 _Counter_type 382 _Counter_type
385 _M_offset() const throw() 383 _M_offset() const throw()
386 { return _M_data_offset * size_t(bits_per_block); } 384 { return _M_data_offset * std::size_t(bits_per_block); }
387 }; 385 };
388 386
389 /** @class _Bitmap_counter bitmap_allocator.h bitmap_allocator.h 387 /** @class _Bitmap_counter bitmap_allocator.h bitmap_allocator.h
390 * 388 *
391 * @brief The bitmap counter which acts as the bitmap 389 * @brief The bitmap counter which acts as the bitmap
400 __detail::__mini_vector<typename std::pair<_Tp, _Tp> > _BPVector; 398 __detail::__mini_vector<typename std::pair<_Tp, _Tp> > _BPVector;
401 typedef typename _BPVector::size_type _Index_type; 399 typedef typename _BPVector::size_type _Index_type;
402 typedef _Tp pointer; 400 typedef _Tp pointer;
403 401
404 _BPVector& _M_vbp; 402 _BPVector& _M_vbp;
405 size_t* _M_curr_bmap; 403 std::size_t* _M_curr_bmap;
406 size_t* _M_last_bmap_in_block; 404 std::size_t* _M_last_bmap_in_block;
407 _Index_type _M_curr_index; 405 _Index_type _M_curr_index;
408 406
409 public: 407 public:
410 // Use the 2nd parameter with care. Make sure that such an 408 // Use the 2nd parameter with care. Make sure that such an
411 // entry exists in the vector before passing that particular 409 // entry exists in the vector before passing that particular
422 _M_curr_index = static_cast<_Index_type>(-1); 420 _M_curr_index = static_cast<_Index_type>(-1);
423 return; 421 return;
424 } 422 }
425 423
426 _M_curr_index = __index; 424 _M_curr_index = __index;
427 _M_curr_bmap = reinterpret_cast<size_t*> 425 _M_curr_bmap = reinterpret_cast<std::size_t*>
428 (_M_vbp[_M_curr_index].first) - 1; 426 (_M_vbp[_M_curr_index].first) - 1;
429 427
430 _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1); 428 _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1);
431 429
432 _M_last_bmap_in_block = _M_curr_bmap 430 _M_last_bmap_in_block = _M_curr_bmap
433 - ((_M_vbp[_M_curr_index].second 431 - ((_M_vbp[_M_curr_index].second
434 - _M_vbp[_M_curr_index].first + 1) 432 - _M_vbp[_M_curr_index].first + 1)
435 / size_t(bits_per_block) - 1); 433 / std::size_t(bits_per_block) - 1);
436 } 434 }
437 435
438 // Dangerous Function! Use with extreme care. Pass to this 436 // Dangerous Function! Use with extreme care. Pass to this
439 // function ONLY those values that are known to be correct, 437 // function ONLY those values that are known to be correct,
440 // otherwise this will mess up big time. 438 // otherwise this will mess up big time.
441 void 439 void
442 _M_set_internal_bitmap(size_t* __new_internal_marker) throw() 440 _M_set_internal_bitmap(std::size_t* __new_internal_marker) throw()
443 { _M_curr_bmap = __new_internal_marker; } 441 { _M_curr_bmap = __new_internal_marker; }
444 442
445 bool 443 bool
446 _M_finished() const throw() 444 _M_finished() const throw()
447 { return(_M_curr_bmap == 0); } 445 { return(_M_curr_bmap == 0); }
459 else 457 else
460 --_M_curr_bmap; 458 --_M_curr_bmap;
461 return *this; 459 return *this;
462 } 460 }
463 461
464 size_t* 462 std::size_t*
465 _M_get() const throw() 463 _M_get() const throw()
466 { return _M_curr_bmap; } 464 { return _M_curr_bmap; }
467 465
468 pointer 466 pointer
469 _M_base() const throw() 467 _M_base() const throw()
470 { return _M_vbp[_M_curr_index].first; } 468 { return _M_vbp[_M_curr_index].first; }
471 469
472 _Index_type 470 _Index_type
473 _M_offset() const throw() 471 _M_offset() const throw()
474 { 472 {
475 return size_t(bits_per_block) 473 return std::size_t(bits_per_block)
476 * ((reinterpret_cast<size_t*>(this->_M_base()) 474 * ((reinterpret_cast<std::size_t*>(this->_M_base())
477 - _M_curr_bmap) - 1); 475 - _M_curr_bmap) - 1);
478 } 476 }
479 477
480 _Index_type 478 _Index_type
481 _M_where() const throw() 479 _M_where() const throw()
484 482
485 /** @brief Mark a memory address as allocated by re-setting the 483 /** @brief Mark a memory address as allocated by re-setting the
486 * corresponding bit in the bit-map. 484 * corresponding bit in the bit-map.
487 */ 485 */
488 inline void 486 inline void
489 __bit_allocate(size_t* __pbmap, size_t __pos) throw() 487 __bit_allocate(std::size_t* __pbmap, std::size_t __pos) throw()
490 { 488 {
491 size_t __mask = 1 << __pos; 489 std::size_t __mask = 1 << __pos;
492 __mask = ~__mask; 490 __mask = ~__mask;
493 *__pbmap &= __mask; 491 *__pbmap &= __mask;
494 } 492 }
495 493
496 /** @brief Mark a memory address as free by setting the 494 /** @brief Mark a memory address as free by setting the
497 * corresponding bit in the bit-map. 495 * corresponding bit in the bit-map.
498 */ 496 */
499 inline void 497 inline void
500 __bit_free(size_t* __pbmap, size_t __pos) throw() 498 __bit_free(std::size_t* __pbmap, std::size_t __pos) throw()
501 { 499 {
502 size_t __mask = 1 << __pos; 500 std::size_t __mask = 1 << __pos;
503 *__pbmap |= __mask; 501 *__pbmap |= __mask;
504 } 502 }
505 } // namespace __detail 503 } // namespace __detail
506 504
507 /** @brief Generic Version of the bsf instruction. 505 /** @brief Generic Version of the bsf instruction.
508 */ 506 */
509 inline size_t 507 inline std::size_t
510 _Bit_scan_forward(size_t __num) 508 _Bit_scan_forward(std::size_t __num)
511 { return static_cast<size_t>(__builtin_ctzl(__num)); } 509 { return static_cast<std::size_t>(__builtin_ctzl(__num)); }
512 510
513 /** @class free_list bitmap_allocator.h bitmap_allocator.h 511 /** @class free_list bitmap_allocator.h bitmap_allocator.h
514 * 512 *
515 * @brief The free list class for managing chunks of memory to be 513 * @brief The free list class for managing chunks of memory to be
516 * given to and returned by the bitmap_allocator. 514 * given to and returned by the bitmap_allocator.
517 */ 515 */
518 class free_list 516 class free_list
519 { 517 {
520 public: 518 public:
521 typedef size_t* value_type; 519 typedef std::size_t* value_type;
522 typedef __detail::__mini_vector<value_type> vector_type; 520 typedef __detail::__mini_vector<value_type> vector_type;
523 typedef vector_type::iterator iterator; 521 typedef vector_type::iterator iterator;
524 typedef __mutex __mutex_type; 522 typedef __mutex __mutex_type;
525 523
526 private: 524 private:
527 struct _LT_pointer_compare 525 struct _LT_pointer_compare
528 { 526 {
529 bool 527 bool
530 operator()(const size_t* __pui, 528 operator()(const std::size_t* __pui,
531 const size_t __cui) const throw() 529 const std::size_t __cui) const throw()
532 { return *__pui < __cui; } 530 { return *__pui < __cui; }
533 }; 531 };
534 532
535 #if defined __GTHREADS 533 #if defined __GTHREADS
536 __mutex_type& 534 __mutex_type&
557 * appropriately performs the action of managing the free list of 555 * appropriately performs the action of managing the free list of
558 * blocks by adding this block to the free list or deleting this 556 * blocks by adding this block to the free list or deleting this
559 * or larger blocks from the free list. 557 * or larger blocks from the free list.
560 */ 558 */
561 void 559 void
562 _M_validate(size_t* __addr) throw() 560 _M_validate(std::size_t* __addr) throw()
563 { 561 {
564 vector_type& __free_list = _M_get_free_list(); 562 vector_type& __free_list = _M_get_free_list();
565 const vector_type::size_type __max_size = 64; 563 const vector_type::size_type __max_size = 64;
566 if (__free_list.size() >= __max_size) 564 if (__free_list.size() >= __max_size)
567 { 565 {
603 * 601 *
604 * @return true if the wastage incurred is acceptable, else returns 602 * @return true if the wastage incurred is acceptable, else returns
605 * false. 603 * false.
606 */ 604 */
607 bool 605 bool
608 _M_should_i_give(size_t __block_size, 606 _M_should_i_give(std::size_t __block_size,
609 size_t __required_size) throw() 607 std::size_t __required_size) throw()
610 { 608 {
611 const size_t __max_wastage_percentage = 36; 609 const std::size_t __max_wastage_percentage = 36;
612 if (__block_size >= __required_size && 610 if (__block_size >= __required_size &&
613 (((__block_size - __required_size) * 100 / __block_size) 611 (((__block_size - __required_size) * 100 / __block_size)
614 < __max_wastage_percentage)) 612 < __max_wastage_percentage))
615 return true; 613 return true;
616 else 614 else
623 * 621 *
624 * @param __addr The pointer to the memory block that was given 622 * @param __addr The pointer to the memory block that was given
625 * by a call to the _M_get function. 623 * by a call to the _M_get function.
626 */ 624 */
627 inline void 625 inline void
628 _M_insert(size_t* __addr) throw() 626 _M_insert(std::size_t* __addr) throw()
629 { 627 {
630 #if defined __GTHREADS 628 #if defined __GTHREADS
631 __scoped_lock __bfl_lock(_M_get_mutex()); 629 __scoped_lock __bfl_lock(_M_get_mutex());
632 #endif 630 #endif
633 // Call _M_validate to decide what should be done with 631 // Call _M_validate to decide what should be done with
634 // this particular free list. 632 // this particular free list.
635 this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1); 633 this->_M_validate(reinterpret_cast<std::size_t*>(__addr) - 1);
636 // See discussion as to why this is 1! 634 // See discussion as to why this is 1!
637 } 635 }
638 636
639 /** @brief This function gets a block of memory of the specified 637 /** @brief This function gets a block of memory of the specified
640 * size from the free list. 638 * size from the free list.
642 * @param __sz The size in bytes of the memory required. 640 * @param __sz The size in bytes of the memory required.
643 * 641 *
644 * @return A pointer to the new memory block of size at least 642 * @return A pointer to the new memory block of size at least
645 * equal to that requested. 643 * equal to that requested.
646 */ 644 */
647 size_t* 645 std::size_t*
648 _M_get(size_t __sz) _GLIBCXX_THROW(std::bad_alloc); 646 _M_get(std::size_t __sz) _GLIBCXX_THROW(std::bad_alloc);
649 647
650 /** @brief This function just clears the internal Free List, and 648 /** @brief This function just clears the internal Free List, and
651 * gives back all the memory to the OS. 649 * gives back all the memory to the OS.
652 */ 650 */
653 void 651 void
682 */ 680 */
683 template<typename _Tp> 681 template<typename _Tp>
684 class bitmap_allocator : private free_list 682 class bitmap_allocator : private free_list
685 { 683 {
686 public: 684 public:
687 typedef size_t size_type; 685 typedef std::size_t size_type;
688 typedef ptrdiff_t difference_type; 686 typedef std::ptrdiff_t difference_type;
689 typedef _Tp* pointer; 687 typedef _Tp* pointer;
690 typedef const _Tp* const_pointer; 688 typedef const _Tp* const_pointer;
691 typedef _Tp& reference; 689 typedef _Tp& reference;
692 typedef const _Tp& const_reference; 690 typedef const _Tp& const_reference;
693 typedef _Tp value_type; 691 typedef _Tp value_type;
704 // 2103. propagate_on_container_move_assignment 702 // 2103. propagate_on_container_move_assignment
705 typedef std::true_type propagate_on_container_move_assignment; 703 typedef std::true_type propagate_on_container_move_assignment;
706 #endif 704 #endif
707 705
708 private: 706 private:
709 template<size_t _BSize, size_t _AlignSize> 707 template<std::size_t _BSize, std::size_t _AlignSize>
710 struct aligned_size 708 struct aligned_size
711 { 709 {
712 enum 710 enum
713 { 711 {
714 modulus = _BSize % _AlignSize, 712 modulus = _BSize % _AlignSize,
752 #endif 750 #endif
753 751
754 /** @brief Responsible for exponentially growing the internal 752 /** @brief Responsible for exponentially growing the internal
755 * memory pool. 753 * memory pool.
756 * 754 *
757 * @throw std::bad_alloc. If memory can not be allocated. 755 * @throw std::bad_alloc. If memory cannot be allocated.
758 * 756 *
759 * Complexity: O(1), but internally depends upon the 757 * Complexity: O(1), but internally depends upon the
760 * complexity of the function free_list::_M_get. The part where 758 * complexity of the function free_list::_M_get. The part where
761 * the bitmap headers are written has complexity: O(X),where X 759 * the bitmap headers are written has complexity: O(X),where X
762 * is the number of blocks of size sizeof(value_type) within 760 * is the number of blocks of size sizeof(value_type) within
763 * the newly acquired block. Having a tight bound. 761 * the newly acquired block. Having a tight bound.
764 */ 762 */
765 void 763 void
766 _S_refill_pool() _GLIBCXX_THROW(std::bad_alloc) 764 _S_refill_pool() _GLIBCXX_THROW(std::bad_alloc)
767 { 765 {
766 using std::size_t;
768 #if defined _GLIBCXX_DEBUG 767 #if defined _GLIBCXX_DEBUG
769 _S_check_for_free_blocks(); 768 _S_check_for_free_blocks();
770 #endif 769 #endif
771 770
772 const size_t __num_bitmaps = (_S_block_size 771 const size_t __num_bitmaps = (_S_block_size
796 795
797 _S_block_size *= 2; 796 _S_block_size *= 2;
798 } 797 }
799 798
800 static _BPVector _S_mem_blocks; 799 static _BPVector _S_mem_blocks;
801 static size_t _S_block_size; 800 static std::size_t _S_block_size;
802 static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request; 801 static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request;
803 static typename _BPVector::size_type _S_last_dealloc_index; 802 static typename _BPVector::size_type _S_last_dealloc_index;
804 #if defined __GTHREADS 803 #if defined __GTHREADS
805 static __mutex_type _S_mut; 804 static __mutex_type _S_mut;
806 #endif 805 #endif
808 public: 807 public:
809 808
810 /** @brief Allocates memory for a single object of size 809 /** @brief Allocates memory for a single object of size
811 * sizeof(_Tp). 810 * sizeof(_Tp).
812 * 811 *
813 * @throw std::bad_alloc. If memory can not be allocated. 812 * @throw std::bad_alloc. If memory cannot be allocated.
814 * 813 *
815 * Complexity: Worst case complexity is O(N), but that 814 * Complexity: Worst case complexity is O(N), but that
816 * is hardly ever hit. If and when this particular case is 815 * is hardly ever hit. If and when this particular case is
817 * encountered, the next few cases are guaranteed to have a 816 * encountered, the next few cases are guaranteed to have a
818 * worst case complexity of O(1)! That's why this function 817 * worst case complexity of O(1)! That's why this function
821 * Amortized Constant time. 820 * Amortized Constant time.
822 */ 821 */
823 pointer 822 pointer
824 _M_allocate_single_object() _GLIBCXX_THROW(std::bad_alloc) 823 _M_allocate_single_object() _GLIBCXX_THROW(std::bad_alloc)
825 { 824 {
825 using std::size_t;
826 #if defined __GTHREADS 826 #if defined __GTHREADS
827 __scoped_lock __bit_lock(_S_mut); 827 __scoped_lock __bit_lock(_S_mut);
828 #endif 828 #endif
829 829
830 // The algorithm is something like this: The last_request 830 // The algorithm is something like this: The last_request
911 * the deallocate function. 911 * the deallocate function.
912 */ 912 */
913 void 913 void
914 _M_deallocate_single_object(pointer __p) throw() 914 _M_deallocate_single_object(pointer __p) throw()
915 { 915 {
916 using std::size_t;
916 #if defined __GTHREADS 917 #if defined __GTHREADS
917 __scoped_lock __bit_lock(_S_mut); 918 __scoped_lock __bit_lock(_S_mut);
918 #endif 919 #endif
919 _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p); 920 _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p);
920 921
1007 { } 1008 { }
1008 1009
1009 ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT 1010 ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
1010 { } 1011 { }
1011 1012
1012 pointer 1013 _GLIBCXX_NODISCARD pointer
1013 allocate(size_type __n) 1014 allocate(size_type __n)
1014 { 1015 {
1015 if (__n > this->max_size()) 1016 if (__n > this->max_size())
1016 std::__throw_bad_alloc(); 1017 std::__throw_bad_alloc();
1017 1018
1031 const size_type __b = __n * sizeof(value_type); 1032 const size_type __b = __n * sizeof(value_type);
1032 return reinterpret_cast<pointer>(::operator new(__b)); 1033 return reinterpret_cast<pointer>(::operator new(__b));
1033 } 1034 }
1034 } 1035 }
1035 1036
1036 pointer 1037 _GLIBCXX_NODISCARD pointer
1037 allocate(size_type __n, typename bitmap_allocator<void>::const_pointer) 1038 allocate(size_type __n, typename bitmap_allocator<void>::const_pointer)
1038 { return allocate(__n); } 1039 { return allocate(__n); }
1039 1040
1040 void 1041 void
1041 deallocate(pointer __p, size_type __n) throw() 1042 deallocate(pointer __p, size_type __n) throw()
1107 template<typename _Tp> 1108 template<typename _Tp>
1108 typename bitmap_allocator<_Tp>::_BPVector 1109 typename bitmap_allocator<_Tp>::_BPVector
1109 bitmap_allocator<_Tp>::_S_mem_blocks; 1110 bitmap_allocator<_Tp>::_S_mem_blocks;
1110 1111
1111 template<typename _Tp> 1112 template<typename _Tp>
1112 size_t bitmap_allocator<_Tp>::_S_block_size = 1113 std::size_t bitmap_allocator<_Tp>::_S_block_size
1113 2 * size_t(__detail::bits_per_block); 1114 = 2 * std::size_t(__detail::bits_per_block);
1114 1115
1115 template<typename _Tp> 1116 template<typename _Tp>
1116 typename bitmap_allocator<_Tp>::_BPVector::size_type 1117 typename bitmap_allocator<_Tp>::_BPVector::size_type
1117 bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; 1118 bitmap_allocator<_Tp>::_S_last_dealloc_index = 0;
1118 1119