Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:34:57

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