Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:06:34

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/container for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_CONTAINER_ADAPTIVE_POOL_HPP
0012 #define BOOST_CONTAINER_ADAPTIVE_POOL_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/container/detail/config_begin.hpp>
0023 #include <boost/container/detail/workaround.hpp>
0024 #include <boost/container/container_fwd.hpp>
0025 #include <boost/container/detail/version_type.hpp>
0026 #include <boost/container/throw_exception.hpp>
0027 #include <boost/container/detail/adaptive_node_pool.hpp>
0028 #include <boost/container/detail/multiallocation_chain.hpp>
0029 #include <boost/container/detail/mpl.hpp>
0030 #include <boost/container/detail/dlmalloc.hpp>
0031 #include <boost/container/detail/singleton.hpp>
0032 #include <boost/container/detail/placement_new.hpp>
0033 
0034 #include <boost/move/detail/force_ptr.hpp>
0035 
0036 #include <boost/assert.hpp>
0037 #include <boost/move/utility_core.hpp>
0038 #include <cstddef>
0039 
0040 
0041 namespace boost {
0042 namespace container {
0043 
0044 //!An STL node allocator that uses a modified DLMalloc as memory
0045 //!source.
0046 //!
0047 //!This node allocator shares a segregated storage between all instances
0048 //!of adaptive_pool with equal sizeof(T).
0049 //!
0050 //!NodesPerBlock is the number of nodes allocated at once when the allocator
0051 //!needs runs out of nodes. MaxFreeBlocks is the maximum number of totally free blocks
0052 //!that the adaptive node pool will hold. The rest of the totally free blocks will be
0053 //!deallocated to the memory manager.
0054 //!
0055 //!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
0056 //!(memory usable for nodes / total memory allocated from the memory allocator)
0057 template < class T
0058          , std::size_t NodesPerBlock   BOOST_CONTAINER_DOCONLY(= ADP_nodes_per_block)
0059          , std::size_t MaxFreeBlocks   BOOST_CONTAINER_DOCONLY(= ADP_max_free_blocks)
0060          , std::size_t OverheadPercent BOOST_CONTAINER_DOCONLY(= ADP_overhead_percent)
0061          BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I unsigned Version)
0062          >
0063 class adaptive_pool
0064 {
0065    //!If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
0066    //!the allocator offers advanced expand in place and burst allocation capabilities.
0067    public:
0068    typedef unsigned int allocation_type;
0069    typedef adaptive_pool
0070       <T, NodesPerBlock, MaxFreeBlocks, OverheadPercent
0071          BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
0072          >   self_t;
0073 
0074    BOOST_STATIC_CONSTEXPR std::size_t nodes_per_block        = NodesPerBlock;
0075    BOOST_STATIC_CONSTEXPR std::size_t max_free_blocks        = MaxFreeBlocks;
0076    BOOST_STATIC_CONSTEXPR std::size_t overhead_percent       = OverheadPercent;
0077    BOOST_STATIC_CONSTEXPR std::size_t real_nodes_per_block   = NodesPerBlock;
0078 
0079    BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_STATIC_ASSERT((Version <=2)));
0080 
0081    public:
0082    //-------
0083    typedef T                                    value_type;
0084    typedef T *                                  pointer;
0085    typedef const T *                            const_pointer;
0086    typedef typename ::boost::container::
0087       dtl::unvoid_ref<T>::type     reference;
0088    typedef typename ::boost::container::
0089       dtl::unvoid_ref<const T>::type     const_reference;
0090    typedef std::size_t                          size_type;
0091    typedef std::ptrdiff_t                       difference_type;
0092 
0093    typedef boost::container::dtl::
0094       version_type<self_t, Version>             version;
0095 
0096    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0097    typedef boost::container::dtl::
0098       basic_multiallocation_chain<void*>              multiallocation_chain_void;
0099    typedef boost::container::dtl::
0100       transform_multiallocation_chain
0101          <multiallocation_chain_void, T>              multiallocation_chain;
0102    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0103 
0104    //!Obtains adaptive_pool from
0105    //!adaptive_pool
0106    template<class T2>
0107    struct rebind
0108    {
0109       typedef adaptive_pool
0110          < T2
0111          , NodesPerBlock
0112          , MaxFreeBlocks
0113          , OverheadPercent
0114          BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
0115          >       other;
0116    };
0117 
0118    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0119    private:
0120    //!Not assignable from related adaptive_pool
0121    template<class T2, std::size_t N2, std::size_t F2, std::size_t O2, unsigned Version2>
0122    adaptive_pool& operator=
0123       (const adaptive_pool<T2, N2, F2, O2, Version2>&);
0124 
0125    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0126 
0127    public:
0128    //!Default constructor
0129    adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
0130    {}
0131 
0132    //!Copy constructor from other adaptive_pool.
0133    adaptive_pool(const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0134    {}
0135 
0136    //!Copy assignment from other adaptive_pool.
0137    adaptive_pool & operator=(const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0138    {  return *this;  }
0139 
0140    //!Copy constructor from related adaptive_pool.
0141    template<class T2>
0142    adaptive_pool
0143       (const adaptive_pool<T2, NodesPerBlock, MaxFreeBlocks, OverheadPercent
0144             BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)> &) BOOST_NOEXCEPT_OR_NOTHROW
0145    {}
0146 
0147    //!Destructor
0148    ~adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
0149    {}
0150 
0151    //!Returns the number of elements that could be allocated.
0152    //!Never throws
0153    size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
0154    {  return size_type(-1)/(2u*sizeof(T));   }
0155 
0156    //!Allocate memory for an array of count elements.
0157    //!Throws bad_alloc if there is no enough memory
0158    pointer allocate(size_type count, const void * = 0)
0159    {
0160       if(BOOST_UNLIKELY(count > size_type(-1)/(2u*sizeof(T))))
0161          boost::container::throw_bad_alloc();
0162 
0163       if(Version == 1 && count == 1){
0164          typedef typename dtl::shared_adaptive_node_pool
0165             <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
0166          typedef dtl::singleton_default<shared_pool_t> singleton_t;
0167          return pointer(static_cast<T*>(singleton_t::instance().allocate_node()));
0168       }
0169       else{
0170          return static_cast<pointer>(dlmalloc_malloc(count*sizeof(T)));
0171       }
0172    }
0173 
0174    //!Deallocate allocated memory.
0175    //!Never throws
0176    void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW
0177    {
0178       (void)count;
0179       if(Version == 1 && count == 1){
0180          typedef dtl::shared_adaptive_node_pool
0181             <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
0182          typedef dtl::singleton_default<shared_pool_t> singleton_t;
0183          singleton_t::instance().deallocate_node(ptr);
0184       }
0185       else{
0186          dlmalloc_free(ptr);
0187       }
0188    }
0189 
0190    pointer allocation_command(allocation_type command,
0191                          size_type limit_size,
0192                          size_type &prefer_in_recvd_out_size,
0193                          pointer &reuse)
0194    {
0195       pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
0196       if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
0197          boost::container::throw_bad_alloc();
0198       return ret;
0199    }
0200 
0201    //!Returns maximum the number of objects the previously allocated memory
0202    //!pointed by p can hold.
0203    size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
0204    {  return dlmalloc_size(p);  }
0205 
0206    //!Allocates just one object. Memory allocated with this function
0207    //!must be deallocated only with deallocate_one().
0208    //!Throws bad_alloc if there is no enough memory
0209    pointer allocate_one()
0210    {
0211       typedef dtl::shared_adaptive_node_pool
0212          <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
0213       typedef dtl::singleton_default<shared_pool_t> singleton_t;
0214       return (pointer)singleton_t::instance().allocate_node();
0215    }
0216 
0217    //!Allocates many elements of size == 1.
0218    //!Elements must be individually deallocated with deallocate_one()
0219    void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
0220    {
0221       typedef dtl::shared_adaptive_node_pool
0222          <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
0223       typedef dtl::singleton_default<shared_pool_t> singleton_t;
0224       singleton_t::instance().allocate_nodes(num_elements, static_cast<typename shared_pool_t::multiallocation_chain&>(chain));
0225       //typename shared_pool_t::multiallocation_chain ch;
0226       //singleton_t::instance().allocate_nodes(num_elements, ch);
0227       //chain.incorporate_after
0228          //(chain.before_begin(), (T*)&*ch.begin(), (T*)&*ch.last(), ch.size());
0229    }
0230 
0231    //!Deallocates memory previously allocated with allocate_one().
0232    //!You should never use deallocate_one to deallocate memory allocated
0233    //!with other functions different from allocate_one(). Never throws
0234    void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
0235    {
0236       typedef dtl::shared_adaptive_node_pool
0237          <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
0238       typedef dtl::singleton_default<shared_pool_t> singleton_t;
0239       singleton_t::instance().deallocate_node(p);
0240    }
0241 
0242    void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
0243    {
0244       typedef dtl::shared_adaptive_node_pool
0245          <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
0246       typedef dtl::singleton_default<shared_pool_t> singleton_t;
0247       //typename shared_pool_t::multiallocation_chain ch(&*chain.begin(), &*chain.last(), chain.size());
0248       //singleton_t::instance().deallocate_nodes(ch);
0249       singleton_t::instance().deallocate_nodes(chain);
0250    }
0251 
0252    //!Allocates many elements of size elem_size.
0253    //!Elements must be individually deallocated with deallocate()
0254    void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
0255    {
0256       BOOST_CONTAINER_STATIC_ASSERT(( Version > 1 ));/*
0257       dlmalloc_memchain ch;
0258       BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
0259       if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
0260          boost::container::throw_bad_alloc();
0261       }
0262       chain.incorporate_after(chain.before_begin()
0263                              ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
0264                              ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
0265                              ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
0266       if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes
0267             ( n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS
0268             , move_detail::force_ptr<dlmalloc_memchain *>(&chain)))){
0269          boost::container::throw_bad_alloc();
0270       }
0271    }
0272 
0273    //!Allocates n_elements elements, each one of size elem_sizes[i]
0274    //!Elements must be individually deallocated with deallocate()
0275    void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
0276    {
0277       BOOST_CONTAINER_STATIC_ASSERT(( Version > 1 ));/*
0278       dlmalloc_memchain ch;
0279       BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
0280       if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
0281          boost::container::throw_bad_alloc();
0282       }
0283       chain.incorporate_after(chain.before_begin()
0284                              ,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
0285                              ,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
0286                              ,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
0287       if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays
0288          ( n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS
0289          , move_detail::force_ptr<dlmalloc_memchain *>(&chain)))){
0290          boost::container::throw_bad_alloc();
0291       }
0292    }
0293 
0294    void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
0295    {/*
0296       dlmalloc_memchain ch;
0297       void *beg(&*chain.begin()), *last(&*chain.last());
0298       size_t size(chain.size());
0299       BOOST_CONTAINER_MEMCHAIN_INIT_FROM(&ch, beg, last, size);
0300       dlmalloc_multidealloc(&ch);*/
0301       dlmalloc_multidealloc(move_detail::force_ptr<dlmalloc_memchain *>(&chain));
0302    }
0303 
0304    //!Deallocates all free blocks of the pool
0305    static void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW
0306    {
0307       typedef dtl::shared_adaptive_node_pool
0308          <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
0309       typedef dtl::singleton_default<shared_pool_t> singleton_t;
0310       singleton_t::instance().deallocate_free_blocks();
0311    }
0312 
0313    //!Swaps allocators. Does not throw. If each allocator is placed in a
0314    //!different memory segment, the result is undefined.
0315    friend void swap(adaptive_pool &, adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0316    {}
0317 
0318    //!An allocator always compares to true, as memory allocated with one
0319    //!instance can be deallocated by another instance
0320    friend bool operator==(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0321    {  return true;   }
0322 
0323    //!An allocator always compares to false, as memory allocated with one
0324    //!instance can be deallocated by another instance
0325    friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0326    {  return false;   }
0327 
0328    private:
0329    pointer priv_allocation_command
0330       (allocation_type command,   std::size_t limit_size
0331       ,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr)
0332    {
0333       std::size_t const preferred_size = prefer_in_recvd_out_size;
0334       dlmalloc_command_ret_t ret = {0 , 0};
0335       if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){
0336          return pointer();
0337       }
0338       std::size_t l_size = limit_size*sizeof(T);
0339       std::size_t p_size = preferred_size*sizeof(T);
0340       std::size_t r_size;
0341       {
0342          void* reuse_ptr_void = reuse_ptr;
0343          ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
0344          reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
0345       }
0346       prefer_in_recvd_out_size = r_size/sizeof(T);
0347       return (pointer)ret.first;
0348    }
0349 };
0350 
0351 
0352 
0353 
0354 
0355 
0356 
0357 
0358 
0359 
0360 
0361 
0362 
0363 
0364 
0365 
0366 
0367 
0368 
0369 
0370 template < class T
0371          , std::size_t NodesPerBlock   = ADP_nodes_per_block
0372          , std::size_t MaxFreeBlocks   = ADP_max_free_blocks
0373          , std::size_t OverheadPercent = ADP_overhead_percent
0374          , unsigned Version = 2
0375          >
0376 class private_adaptive_pool
0377 {
0378    //!If Version is 1, the allocator is a STL conforming allocator. If Version is 2,
0379    //!the allocator offers advanced expand in place and burst allocation capabilities.
0380    public:
0381    typedef unsigned int allocation_type;
0382    typedef private_adaptive_pool
0383       <T, NodesPerBlock, MaxFreeBlocks, OverheadPercent
0384          BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
0385          >   self_t;
0386 
0387    BOOST_STATIC_CONSTEXPR std::size_t nodes_per_block        = NodesPerBlock;
0388    BOOST_STATIC_CONSTEXPR std::size_t max_free_blocks        = MaxFreeBlocks;
0389    BOOST_STATIC_CONSTEXPR std::size_t overhead_percent       = OverheadPercent;
0390    BOOST_STATIC_CONSTEXPR std::size_t real_nodes_per_block   = NodesPerBlock;
0391 
0392    BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_STATIC_ASSERT((Version <=2)));
0393 
0394    typedef dtl::private_adaptive_node_pool
0395       <sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> pool_t;
0396    pool_t m_pool;
0397 
0398    public:
0399    //-------
0400    typedef T                                    value_type;
0401    typedef T *                                  pointer;
0402    typedef const T *                            const_pointer;
0403    typedef typename ::boost::container::
0404       dtl::unvoid_ref<T>::type     reference;
0405    typedef typename ::boost::container::
0406       dtl::unvoid_ref<const T>::type            const_reference;
0407    typedef std::size_t                          size_type;
0408    typedef std::ptrdiff_t                       difference_type;
0409 
0410    typedef boost::container::dtl::
0411       version_type<self_t, Version>             version;
0412 
0413    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0414    typedef boost::container::dtl::
0415       basic_multiallocation_chain<void*>              multiallocation_chain_void;
0416    typedef boost::container::dtl::
0417       transform_multiallocation_chain
0418          <multiallocation_chain_void, T>              multiallocation_chain;
0419    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0420 
0421    //!Obtains private_adaptive_pool from
0422    //!private_adaptive_pool
0423    template<class T2>
0424    struct rebind
0425    {
0426       typedef private_adaptive_pool
0427          < T2
0428          , NodesPerBlock
0429          , MaxFreeBlocks
0430          , OverheadPercent
0431          BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
0432          >       other;
0433    };
0434 
0435    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0436    private:
0437    //!Not assignable from related private_adaptive_pool
0438    template<class T2, std::size_t N2, std::size_t F2, std::size_t O2, unsigned Version2>
0439    private_adaptive_pool& operator=
0440       (const private_adaptive_pool<T2, N2, F2, O2, Version2>&);
0441    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0442 
0443    public:
0444    //!Default constructor
0445    private_adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
0446    {}
0447 
0448    //!Copy constructor from other private_adaptive_pool.
0449    private_adaptive_pool(const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0450    {}
0451 
0452    //!Copy assignment from other adaptive_pool.
0453    private_adaptive_pool & operator=(const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0454    {  return *this;  }
0455 
0456    //!Copy constructor from related private_adaptive_pool.
0457    template<class T2>
0458    private_adaptive_pool
0459       (const private_adaptive_pool<T2, NodesPerBlock, MaxFreeBlocks, OverheadPercent
0460             BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)> &) BOOST_NOEXCEPT_OR_NOTHROW
0461    {}
0462 
0463    //!Destructor
0464    ~private_adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
0465    {}
0466 
0467    //!Returns the number of elements that could be allocated.
0468    //!Never throws
0469    size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
0470    {  return size_type(-1)/(2u*sizeof(T));   }
0471 
0472    //!Allocate memory for an array of count elements.
0473    //!Throws bad_alloc if there is no enough memory
0474    pointer allocate(size_type count, const void * = 0)
0475    {
0476       if(BOOST_UNLIKELY(count > size_type(-1)/(2u*sizeof(T))))
0477          boost::container::throw_bad_alloc();
0478 
0479       if(Version == 1 && count == 1){
0480          return pointer(static_cast<T*>(m_pool.allocate_node()));
0481       }
0482       else{
0483          return static_cast<pointer>(dlmalloc_malloc(count*sizeof(T)));
0484       }
0485    }
0486 
0487    //!Deallocate allocated memory.
0488    //!Never throws
0489    void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW
0490    {
0491       (void)count;
0492       if(Version == 1 && count == 1){
0493          m_pool.deallocate_node(ptr);
0494       }
0495       else{
0496          dlmalloc_free(ptr);
0497       }
0498    }
0499 
0500    pointer allocation_command(allocation_type command,
0501                          size_type limit_size,
0502                          size_type &prefer_in_recvd_out_size,
0503                          pointer &reuse)
0504    {
0505       pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
0506       if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
0507          boost::container::throw_bad_alloc();
0508       return ret;
0509    }
0510 
0511    //!Returns maximum the number of objects the previously allocated memory
0512    //!pointed by p can hold.
0513    size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
0514    {  return dlmalloc_size(p);  }
0515 
0516    //!Allocates just one object. Memory allocated with this function
0517    //!must be deallocated only with deallocate_one().
0518    //!Throws bad_alloc if there is no enough memory
0519    pointer allocate_one()
0520    {
0521       return (pointer)m_pool.allocate_node();
0522    }
0523 
0524    //!Allocates many elements of size == 1.
0525    //!Elements must be individually deallocated with deallocate_one()
0526    void allocate_individual(std::size_t num_elements, multiallocation_chain &chain)
0527    {
0528       m_pool.allocate_nodes(num_elements, static_cast<typename pool_t::multiallocation_chain&>(chain));
0529    }
0530 
0531    //!Deallocates memory previously allocated with allocate_one().
0532    //!You should never use deallocate_one to deallocate memory allocated
0533    //!with other functions different from allocate_one(). Never throws
0534    void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
0535    {
0536       m_pool.deallocate_node(p);
0537    }
0538 
0539    void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
0540    {
0541       m_pool.deallocate_nodes(chain);
0542    }
0543 
0544    //!Allocates many elements of size elem_size.
0545    //!Elements must be individually deallocated with deallocate()
0546    void allocate_many(size_type elem_size, std::size_t n_elements, multiallocation_chain &chain)
0547    {
0548       BOOST_CONTAINER_STATIC_ASSERT(( Version > 1 ));
0549       if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes
0550             ( n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS
0551             , move_detail::force_ptr<dlmalloc_memchain *>(&chain)))){
0552          boost::container::throw_bad_alloc();
0553       }
0554    }
0555 
0556    //!Allocates n_elements elements, each one of size elem_sizes[i]
0557    //!Elements must be individually deallocated with deallocate()
0558    void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
0559    {
0560       BOOST_CONTAINER_STATIC_ASSERT(( Version > 1 ));
0561       if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays
0562          (n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS
0563          , move_detail::force_ptr<dlmalloc_memchain *>(&chain)))){
0564          boost::container::throw_bad_alloc();
0565       }
0566    }
0567 
0568    void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
0569    {
0570       dlmalloc_multidealloc(move_detail::force_ptr<dlmalloc_memchain *>(&chain));
0571    }
0572 
0573    //!Deallocates all free blocks of the pool
0574    void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW
0575    {
0576       m_pool.deallocate_free_blocks();
0577    }
0578 
0579    //!Swaps allocators. Does not throw. If each allocator is placed in a
0580    //!different memory segment, the result is undefined.
0581    friend void swap(private_adaptive_pool &, private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0582    {}
0583 
0584    //!An allocator always compares to true, as memory allocated with one
0585    //!instance can be deallocated by another instance
0586    friend bool operator==(const private_adaptive_pool &, const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0587    {  return true;   }
0588 
0589    //!An allocator always compares to false, as memory allocated with one
0590    //!instance can be deallocated by another instance
0591    friend bool operator!=(const private_adaptive_pool &, const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
0592    {  return false;   }
0593 
0594    private:
0595    pointer priv_allocation_command
0596       (allocation_type command,   std::size_t limit_size
0597       ,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr)
0598    {
0599       std::size_t const preferred_size = prefer_in_recvd_out_size;
0600       dlmalloc_command_ret_t ret = {0 , 0};
0601       if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){
0602          return pointer();
0603       }
0604       std::size_t l_size = limit_size*sizeof(T);
0605       std::size_t p_size = preferred_size*sizeof(T);
0606       std::size_t r_size;
0607       {
0608          void* reuse_ptr_void = reuse_ptr;
0609          ret = dlmalloc_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
0610          reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
0611       }
0612       prefer_in_recvd_out_size = r_size/sizeof(T);
0613       return (pointer)ret.first;
0614    }
0615 };
0616 
0617 }  //namespace container {
0618 }  //namespace boost {
0619 
0620 #include <boost/container/detail/config_end.hpp>
0621 
0622 #endif   //#ifndef BOOST_CONTAINER_ADAPTIVE_POOL_HPP