29#ifndef _BITMAP_ALLOCATOR_H 
   30#define _BITMAP_ALLOCATOR_H 1 
   43#define _BALLOC_ALIGN_BYTES 8 
   45namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 
   47_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   66    template<
typename _Tp>
 
   73        typedef _Tp value_type;
 
   75        typedef _Tp& reference;
 
   76        typedef const _Tp& const_reference;
 
   77        typedef std::size_t size_type;
 
   78        typedef std::ptrdiff_t difference_type;
 
   79        typedef pointer iterator;
 
   84        pointer _M_end_of_storage;
 
   87        _M_space_left() 
const throw()
 
   88        { 
return _M_end_of_storage - _M_finish; }
 
   90        _GLIBCXX_NODISCARD pointer
 
   91        allocate(size_type __n)
 
   92        { 
return static_cast<pointer
>(::operator 
new(__n * 
sizeof(_Tp))); }
 
   95        deallocate(pointer __p, size_type)
 
   96        { ::operator 
delete(__p); }
 
  104        : _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
 
  108        { 
return _M_finish - _M_start; }
 
  111        begin() 
const throw()
 
  112        { 
return this->_M_start; }
 
  116        { 
return this->_M_finish; }
 
  120        { 
return *(this->end() - 1); }
 
  123        operator[](
const size_type __pos) 
const throw()
 
  124        { 
return this->_M_start[__pos]; }
 
  127        insert(iterator __pos, const_reference __x);
 
  130        push_back(const_reference __x)
 
  132          if (this->_M_space_left())
 
  138            this->insert(this->end(), __x);
 
  143        { --this->_M_finish; }
 
  146        erase(iterator __pos) 
throw();
 
  150        { this->_M_finish = this->_M_start; }
 
  154    template<
typename _Tp>
 
  156      insert(iterator __pos, const_reference __x)
 
  158        if (this->_M_space_left())
 
  160            size_type __to_move = this->_M_finish - __pos;
 
  161            iterator __dest = this->end();
 
  162            iterator __src = this->end() - 1;
 
  168                --__dest; --__src; --__to_move;
 
  174            size_type __new_size = this->size() ? this->size() * 2 : 1;
 
  175            iterator __new_start = this->allocate(__new_size);
 
  176            iterator __first = this->begin();
 
  177            iterator __start = __new_start;
 
  178            while (__first != __pos)
 
  181                ++__start; ++__first;
 
  185            while (__first != this->end())
 
  188                ++__start; ++__first;
 
  191              this->deallocate(this->_M_start, this->size());
 
  193            this->_M_start = __new_start;
 
  194            this->_M_finish = __start;
 
  195            this->_M_end_of_storage = this->_M_start + __new_size;
 
  199    template<
typename _Tp>
 
  200      void __mini_vector<_Tp>::
 
  201      erase(iterator __pos) 
throw()
 
  203        while (__pos + 1 != this->end())
 
  212    template<
typename _Tp>
 
  213      struct __mv_iter_traits
 
  215        typedef typename _Tp::value_type value_type;
 
  216        typedef typename _Tp::difference_type difference_type;
 
  219    template<
typename _Tp>
 
  220      struct __mv_iter_traits<_Tp*>
 
  222        typedef _Tp value_type;
 
  223        typedef std::ptrdiff_t difference_type;
 
  229        bits_per_block = 
sizeof(std::size_t) * std::size_t(bits_per_byte)
 
  232    template<
typename _ForwardIterator, 
typename _Tp, 
typename _Compare>
 
  234      __lower_bound(_ForwardIterator __first, _ForwardIterator __last,
 
  235                    const _Tp& __val, _Compare __comp)
 
  237        typedef typename __mv_iter_traits<_ForwardIterator>::difference_type
 
  240        _DistanceType __len = __last - __first;
 
  241        _DistanceType __half;
 
  242        _ForwardIterator __middle;
 
  249            if (__comp(*__middle, __val))
 
  253                __len = __len - __half - 1;
 
  264    template<
typename _AddrPair>
 
  267      { 
return (__ap.second - __ap.first) + 1; }
 
  272    template<
typename _AddrPair>
 
  275      { 
return __num_blocks(__ap) / std::size_t(bits_per_block); }
 
  278    template<
typename _Tp>
 
  279      class _Inclusive_between 
 
  282        pointer _M_ptr_value;
 
  286        _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr) 
 
  290        operator()(_Block_pair __bp) 
const throw()
 
  301    template<
typename _Functor>
 
  307        typedef typename _Functor::argument_type argument_type;
 
  308        typedef typename _Functor::result_type result_type;
 
  310        _Functor_Ref(_Functor& __fref) : _M_fref(__fref) 
 
  314        operator()(argument_type __arg) 
 
  315        { 
return _M_fref(__arg); }
 
  325    template<
typename _Tp>
 
  330        typedef typename _BPVector::difference_type _Counter_type;
 
  332        std::size_t* _M_pbitmap;
 
  333        _Counter_type _M_data_offset;
 
  336        typedef bool result_type;
 
  358          if (*(
reinterpret_cast<size_t*
> 
  362          size_t* __rover = 
reinterpret_cast<size_t*
>(__bp.
first) - 1;
 
  364          for (_Counter_type __i = 0; __i < __diff; ++__i)
 
  366              _M_data_offset = __i;
 
  369                  _M_pbitmap = __rover;
 
  378        _M_get() 
const throw()
 
  379        { 
return _M_pbitmap; }
 
  382        _M_offset() 
const throw()
 
  383        { 
return _M_data_offset * std::size_t(bits_per_block); }
 
  393    template<
typename _Tp>
 
  398        typedef typename _BPVector::size_type _Index_type;
 
  402        std::size_t* _M_curr_bmap;
 
  403        std::size_t* _M_last_bmap_in_block;
 
  404        _Index_type _M_curr_index;
 
  411        { this->_M_reset(__index); }
 
  414        _M_reset(
long __index = -1) 
throw()
 
  419              _M_curr_index = 
static_cast<_Index_type
>(-1);
 
  423          _M_curr_index = __index;
 
  424          _M_curr_bmap = 
reinterpret_cast<std::size_t*
> 
  425            (_M_vbp[_M_curr_index].first) - 1;
 
  427          _GLIBCXX_DEBUG_ASSERT(__index <= (
long)_M_vbp.size() - 1);
 
  429          _M_last_bmap_in_block = _M_curr_bmap
 
  430            - ((_M_vbp[_M_curr_index].second 
 
  431                - _M_vbp[_M_curr_index].first + 1) 
 
  432               / std::size_t(bits_per_block) - 1);
 
  439        _M_set_internal_bitmap(std::size_t* __new_internal_marker) 
throw()
 
  440        { _M_curr_bmap = __new_internal_marker; }
 
  443        _M_finished() 
const throw()
 
  444        { 
return(_M_curr_bmap == 0); }
 
  449          if (_M_curr_bmap == _M_last_bmap_in_block)
 
  451              if (++_M_curr_index == _M_vbp.size())
 
  454                this->_M_reset(_M_curr_index);
 
  462        _M_get() 
const throw()
 
  463        { 
return _M_curr_bmap; }
 
  466        _M_base() 
const throw()
 
  467        { 
return _M_vbp[_M_curr_index].first; }
 
  470        _M_offset() 
const throw()
 
  472          return std::size_t(bits_per_block)
 
  473            * ((
reinterpret_cast<std::size_t*
>(this->_M_base())
 
  474                - _M_curr_bmap) - 1);
 
  478        _M_where() 
const throw()
 
  479        { 
return _M_curr_index; }
 
  488      std::size_t __mask = 1 << __pos;
 
  499      std::size_t __mask = 1 << __pos;
 
  508  { 
return static_cast<std::size_t
>(__builtin_ctzl(__num)); }
 
  518    typedef std::size_t*                        value_type;
 
  520    typedef vector_type::iterator               iterator;
 
  521    typedef __mutex                             __mutex_type;
 
  524    struct _LT_pointer_compare
 
  527      operator()(
const std::size_t* __pui,
 
  528                 const std::size_t __cui) 
const throw()
 
  529      { 
return *__pui < __cui; }
 
  532#if defined __GTHREADS 
  536      static __mutex_type _S_mutex;
 
  559    _M_validate(std::size_t* __addr) 
throw()
 
  562      const vector_type::size_type __max_size = 64;
 
  563      if (__free_list.size() >= __max_size)
 
  567          if (*__addr >= *__free_list.back())
 
  572              ::operator 
delete(
static_cast<void*
>(__addr));
 
  579              ::operator 
delete(
static_cast<void*
>(__free_list.back()));
 
  580              __free_list.pop_back();
 
  585      iterator __temp = __detail::__lower_bound
 
  586        (__free_list.begin(), __free_list.end(), 
 
  587         *__addr, _LT_pointer_compare());
 
  590      __free_list.insert(__temp, __addr);
 
  605    _M_should_i_give(std::size_t __block_size,
 
  606                     std::size_t __required_size) 
throw()
 
  608      const std::size_t __max_wastage_percentage = 36;
 
  609      if (__block_size >= __required_size && 
 
  610          (((__block_size - __required_size) * 100 / __block_size)
 
  611           < __max_wastage_percentage))
 
  627#if defined __GTHREADS 
  632      this->_M_validate(
reinterpret_cast<std::size_t*
>(__addr) - 1);
 
  656  template<
typename _Tp> 
 
  664      typedef void*       pointer;
 
  665      typedef const void* const_pointer;
 
  668      typedef void  value_type;
 
  669      template<
typename _Tp1>
 
  680  template<
typename _Tp>
 
  684      typedef std::size_t               size_type;
 
  685      typedef std::ptrdiff_t            difference_type;
 
  686      typedef _Tp*                      pointer;
 
  687      typedef const _Tp*                const_pointer;
 
  688      typedef _Tp&                      reference;
 
  689      typedef const _Tp&                const_reference;
 
  690      typedef _Tp                       value_type;
 
  691      typedef free_list::__mutex_type   __mutex_type;
 
  693      template<
typename _Tp1>
 
  699#if __cplusplus >= 201103L 
  706      template<std::
size_t _BSize, std::
size_t _AlignSize>
 
  711              modulus = _BSize % _AlignSize,
 
  712              value = _BSize + (modulus ? _AlignSize - (modulus) : 0)
 
  718        char __M_unused[aligned_size<
sizeof(value_type),
 
  726      typedef typename _BPVector::iterator _BPiter;
 
  728      template<
typename _Predicate>
 
  730        _S_find(_Predicate __p)
 
  732          _BPiter __first = _S_mem_blocks.begin();
 
  733          while (__first != _S_mem_blocks.end() && !__p(*__first))
 
  738#if defined _GLIBCXX_DEBUG 
  742      _S_check_for_free_blocks() 
throw()
 
  745        _BPiter __bpi = _S_find(_FFF());
 
  747        _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end());
 
  766#if defined _GLIBCXX_DEBUG 
  767        _S_check_for_free_blocks();
 
  770        const size_t __num_bitmaps = (_S_block_size
 
  771                                      / size_t(__detail::bits_per_block));
 
  772        const size_t __size_to_allocate = 
sizeof(size_t) 
 
  773          + _S_block_size * 
sizeof(_Alloc_block) 
 
  774          + __num_bitmaps * 
sizeof(size_t);
 
  777          reinterpret_cast<size_t*
>(this->
_M_get(__size_to_allocate));
 
  783          std::make_pair(
reinterpret_cast<_Alloc_block*
> 
  784                         (__temp + __num_bitmaps), 
 
  785                         reinterpret_cast<_Alloc_block*
> 
  786                         (__temp + __num_bitmaps) 
 
  787                         + _S_block_size - 1);
 
  790        _S_mem_blocks.push_back(__bp);
 
  792        for (
size_t __i = 0; __i < __num_bitmaps; ++__i)
 
  793          __temp[__i] = ~
static_cast<size_t>(0); 
 
  799      static std::size_t _S_block_size;
 
  801      static typename _BPVector::size_type _S_last_dealloc_index;
 
  802#if defined __GTHREADS 
  803      static __mutex_type _S_mut;
 
  825#if defined __GTHREADS 
  842        while (_S_last_request._M_finished() == 
false 
  843               && (*(_S_last_request._M_get()) == 0))
 
  844          _S_last_request.operator++();
 
  846        if (__builtin_expect(_S_last_request._M_finished() == 
true, 
false))
 
  851            _BPiter __bpi = _S_find(__detail::_Functor_Ref<_FFF>(__fff));
 
  853            if (__bpi != _S_mem_blocks.end())
 
  861                _S_last_request._M_reset(__bpi - _S_mem_blocks.begin());
 
  864                pointer __ret = 
reinterpret_cast<pointer
> 
  865                  (__bpi->first + __fff._M_offset() + __nz_bit);
 
  866                size_t* __puse_count = 
 
  867                  reinterpret_cast<size_t*
> 
  881                _S_last_request._M_reset(_S_mem_blocks.size() - 1);
 
  892        pointer __ret = 
reinterpret_cast<pointer
> 
  893          (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit);
 
  895        size_t* __puse_count = 
reinterpret_cast<size_t*
> 
  896          (_S_mem_blocks[_S_last_request._M_where()].first)
 
  898             __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1);
 
  916#if defined __GTHREADS 
  919        _Alloc_block* __real_p = 
reinterpret_cast<_Alloc_block*
>(__p);
 
  921        typedef typename _BPVector::iterator _Iterator;
 
  922        typedef typename _BPVector::difference_type _Difference_type;
 
  924        _Difference_type __diff;
 
  927        _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
 
  929        __detail::_Inclusive_between<_Alloc_block*> __ibt(__real_p);
 
  930        if (__ibt(_S_mem_blocks[_S_last_dealloc_index]))
 
  932            _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index
 
  933                                  <= _S_mem_blocks.size() - 1);
 
  936            __diff = _S_last_dealloc_index;
 
  937            __displacement = __real_p - _S_mem_blocks[__diff].first;
 
  941            _Iterator _iter = _S_find(__ibt);
 
  943            _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end());
 
  945            __diff = _iter - _S_mem_blocks.begin();
 
  946            __displacement = __real_p - _S_mem_blocks[__diff].first;
 
  947            _S_last_dealloc_index = __diff;
 
  951        const size_t __rotate = (__displacement
 
  952                                 % size_t(__detail::bits_per_block));
 
  954          reinterpret_cast<size_t*
> 
  955          (_S_mem_blocks[__diff].first) - 1;
 
  956        __bitmapC -= (__displacement / size_t(__detail::bits_per_block));
 
  959        size_t* __puse_count = 
reinterpret_cast<size_t*
> 
  960          (_S_mem_blocks[__diff].first)
 
  963        _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0);
 
  967        if (__builtin_expect(*__puse_count == 0, 
false))
 
  974            _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff);
 
  982            if ((_Difference_type)_S_last_request._M_where() >= __diff--)
 
  983              _S_last_request._M_reset(__diff); 
 
  990            if (_S_last_dealloc_index >= _S_mem_blocks.size())
 
  992                _S_last_dealloc_index =(__diff != -1 ? __diff : 0);
 
  993                _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0);
 
 1002      bitmap_allocator(
const bitmap_allocator&) _GLIBCXX_USE_NOEXCEPT
 
 1005      template<
typename _Tp1>
 
 1006        bitmap_allocator(
const bitmap_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT
 
 1009      ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT
 
 1012      _GLIBCXX_NODISCARD pointer 
 
 1013      allocate(size_type __n)
 
 1015        if (__n > this->max_size())
 
 1016          std::__throw_bad_alloc();
 
 1018#if __cpp_aligned_new 
 1019        if (
alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
 
 1021            const size_type __b = __n * 
sizeof(value_type);
 
 1022            std::align_val_t __al = std::align_val_t(
alignof(value_type));
 
 1023            return static_cast<pointer
>(::operator 
new(__b, __al));
 
 1027        if (__builtin_expect(__n == 1, 
true))
 
 1031            const size_type __b = __n * 
sizeof(value_type);
 
 1032            return reinterpret_cast<pointer
>(::operator 
new(__b));
 
 1036      _GLIBCXX_NODISCARD pointer 
 
 1037      allocate(size_type __n, 
typename bitmap_allocator<void>::const_pointer)
 
 1038      { 
return allocate(__n); }
 
 1041      deallocate(pointer __p, size_type __n) 
throw()
 
 1043        if (__builtin_expect(__p != 0, 
true))
 
 1045#if __cpp_aligned_new 
 1047            if (
alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
 
 1049                ::operator 
delete(__p, std::align_val_t(
alignof(value_type)));
 
 1054            if (__builtin_expect(__n == 1, 
true))
 
 1057              ::operator 
delete(__p);
 
 1062      address(reference __r) 
const _GLIBCXX_NOEXCEPT
 
 1066      address(const_reference __r) 
const _GLIBCXX_NOEXCEPT
 
 1070      max_size() const _GLIBCXX_USE_NOEXCEPT
 
 1071      { 
return size_type(-1) / 
sizeof(value_type); }
 
 1073#if __cplusplus >= 201103L 
 1074      template<
typename _Up, 
typename... _Args>
 
 1076        construct(_Up* __p, _Args&&... __args)
 
 1077        { ::new((
void *)__p) _Up(std::forward<_Args>(__args)...); }
 
 1079      template<
typename _Up>
 
 1085      construct(pointer __p, const_reference __data)
 
 1086      { ::new((
void *)__p) value_type(__data); }
 
 1089      destroy(pointer __p)
 
 1090      { __p->~value_type(); }
 
 1094  template<
typename _Tp1, 
typename _Tp2>
 
 1096    operator==(
const bitmap_allocator<_Tp1>&, 
 
 1097               const bitmap_allocator<_Tp2>&) 
throw()
 
 1100#if __cpp_impl_three_way_comparison < 201907L 
 1101  template<
typename _Tp1, 
typename _Tp2>
 
 1103    operator!=(
const bitmap_allocator<_Tp1>&, 
 
 1104               const bitmap_allocator<_Tp2>&) 
throw() 
 
 1109  template<
typename _Tp>
 
 1110    typename bitmap_allocator<_Tp>::_BPVector
 
 1111    bitmap_allocator<_Tp>::_S_mem_blocks;
 
 1113  template<
typename _Tp>
 
 1114    std::size_t bitmap_allocator<_Tp>::_S_block_size
 
 1115      = 2 * std::size_t(__detail::bits_per_block);
 
 1117  template<
typename _Tp>
 
 1118    typename bitmap_allocator<_Tp>::_BPVector::size_type 
 
 1119    bitmap_allocator<_Tp>::_S_last_dealloc_index = 0;
 
 1121  template<
typename _Tp>
 
 1122    __detail::_Bitmap_counter
 
 1123      <
typename bitmap_allocator<_Tp>::_Alloc_block*>
 
 1124    bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks);
 
 1126#if defined __GTHREADS 
 1127  template<
typename _Tp>
 
 1128    typename bitmap_allocator<_Tp>::__mutex_type
 
 1129    bitmap_allocator<_Tp>::_S_mut;
 
 1132_GLIBCXX_END_NAMESPACE_VERSION
 
#define _BALLOC_ALIGN_BYTES
The constant in the expression below is the alignment required in bytes.
 
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
 
ISO C++ entities toplevel namespace is std.
 
GNU extensions for public use.
 
std::size_t _Bit_scan_forward(std::size_t __num)
Generic Version of the bsf instruction.
 
void __bit_free(std::size_t *__pbmap, std::size_t __pos)
Mark a memory address as free by setting the corresponding bit in the bit-map.
 
std::size_t __num_bitmaps(_AddrPair __ap)
The number of Bit-maps pointed to by the address pair passed to the function.
 
void __bit_allocate(std::size_t *__pbmap, std::size_t __pos)
Mark a memory address as allocated by re-setting the corresponding bit in the bit-map.
 
std::size_t __num_blocks(_AddrPair __ap)
The number of Blocks pointed to by the address pair passed to the function.
 
Exception possibly thrown by new.
 
One of the comparison functors.
 
One of the comparison functors.
 
Struct holding two objects of arbitrary type.
 
_T1 first
The first member.
 
__mini_vector<> is a stripped down version of the full-fledged std::vector<>.
 
The class which acts as a predicate for applying the first-fit memory allocation policy for the bitma...
 
The bitmap counter which acts as the bitmap manipulator, and manages the bit-manipulation functions a...
 
The free list class for managing chunks of memory to be given to and returned by the bitmap_allocator...
 
std::size_t * _M_get(std::size_t __sz)
This function gets a block of memory of the specified size from the free list.
 
void _M_insert(std::size_t *__addr)
This function returns the block of memory to the internal free list.
 
void _M_clear()
This function just clears the internal Free List, and gives back all the memory to the OS.
 
Bitmap Allocator, primary template.
 
pointer _M_allocate_single_object()
Allocates memory for a single object of size sizeof(_Tp).
 
void _M_deallocate_single_object(pointer __p)
Deallocates memory that belongs to a single object of size sizeof(_Tp).