Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:09

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2012-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_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
0012 #define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_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 
0025 #include <boost/container/allocator_traits.hpp>             //allocator_traits
0026 #include <boost/container/throw_exception.hpp>
0027 #include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
0028 #include <boost/container/detail/version_type.hpp>          //version_type
0029 #include <boost/container/detail/allocation_type.hpp>       //allocation_type
0030 #include <boost/container/detail/mpl.hpp>                   //integral_constant
0031 #include <boost/intrusive/pointer_traits.hpp>               //pointer_traits
0032 
0033 namespace boost {
0034 namespace container {
0035 namespace dtl {
0036 
0037 template<class Allocator, unsigned Version = boost::container::dtl::version<Allocator>::value>
0038 struct allocator_version_traits
0039 {
0040    typedef ::boost::container::dtl::integral_constant
0041       <unsigned, Version> alloc_version;
0042 
0043    typedef typename Allocator::multiallocation_chain multiallocation_chain;
0044 
0045    typedef typename boost::container::allocator_traits<Allocator>::pointer    pointer;
0046    typedef typename boost::container::allocator_traits<Allocator>::size_type  size_type;
0047 
0048    //Node allocation interface
0049    BOOST_CONTAINER_FORCEINLINE static pointer allocate_one(Allocator &a)
0050    {  return a.allocate_one();   }
0051 
0052    BOOST_CONTAINER_FORCEINLINE static void deallocate_one(Allocator &a, const pointer &p)
0053    {  a.deallocate_one(p);   }
0054 
0055    BOOST_CONTAINER_FORCEINLINE static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
0056    {  return a.allocate_individual(n, m);   }
0057 
0058    BOOST_CONTAINER_FORCEINLINE static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
0059    {  a.deallocate_individual(holder);   }
0060 
0061    BOOST_CONTAINER_FORCEINLINE static pointer allocation_command(Allocator &a, allocation_type command,
0062                          size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
0063    {  return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);  }
0064 };
0065 
0066 template<class Allocator>
0067 struct allocator_version_traits<Allocator, 1>
0068 {
0069    typedef ::boost::container::dtl::integral_constant
0070       <unsigned, 1> alloc_version;
0071 
0072    typedef typename boost::container::allocator_traits<Allocator>::pointer    pointer;
0073    typedef typename boost::container::allocator_traits<Allocator>::size_type  size_type;
0074    typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
0075 
0076    typedef typename boost::intrusive::pointer_traits<pointer>::
0077          template rebind_pointer<void>::type                void_ptr;
0078    typedef dtl::basic_multiallocation_chain
0079       <void_ptr>                                            multialloc_cached_counted;
0080    typedef boost::container::dtl::
0081       transform_multiallocation_chain
0082          < multialloc_cached_counted, value_type>           multiallocation_chain;
0083 
0084    //Node allocation interface
0085    BOOST_CONTAINER_FORCEINLINE static pointer allocate_one(Allocator &a)
0086    {  return a.allocate(1);   }
0087 
0088    BOOST_CONTAINER_FORCEINLINE static void deallocate_one(Allocator &a, const pointer &p)
0089    {  a.deallocate(p, 1);   }
0090 
0091    static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
0092    {
0093       size_type n = holder.size();
0094       typename multiallocation_chain::iterator it = holder.begin();
0095       while(n){
0096          --n;
0097          pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it);
0098          ++it;
0099          a.deallocate(p, 1);
0100       }
0101    }
0102 
0103    struct allocate_individual_rollback
0104    {
0105       BOOST_CONTAINER_FORCEINLINE allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
0106          : mr_a(a), mp_chain(&chain)
0107       {}
0108 
0109       BOOST_CONTAINER_FORCEINLINE ~allocate_individual_rollback()
0110       {
0111          if(mp_chain)
0112             allocator_version_traits::deallocate_individual(mr_a, *mp_chain);
0113       }
0114 
0115       BOOST_CONTAINER_FORCEINLINE void release()
0116       {
0117          mp_chain = 0;
0118       }
0119 
0120       Allocator &mr_a;
0121       multiallocation_chain * mp_chain;
0122    };
0123 
0124    static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
0125    {
0126       allocate_individual_rollback rollback(a, m);
0127       while(n--){
0128          m.push_front(a.allocate(1));
0129       }
0130       rollback.release();
0131    }
0132 
0133    static pointer allocation_command(Allocator &a, allocation_type command,
0134                          size_type, size_type &prefer_in_recvd_out_size, pointer &reuse)
0135    {
0136       pointer ret = pointer();
0137       if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){
0138          throw_logic_error("version 1 allocator without allocate_new flag");
0139       }
0140       else{
0141          BOOST_CONTAINER_TRY{
0142             ret = a.allocate(prefer_in_recvd_out_size);
0143          }
0144          BOOST_CONTAINER_CATCH(...){
0145             if(!(command & nothrow_allocation)){
0146                BOOST_CONTAINER_RETHROW
0147             }
0148          }
0149          BOOST_CONTAINER_CATCH_END
0150          reuse = pointer();
0151       }
0152       return ret;
0153    }
0154 };
0155 
0156 }  //namespace dtl {
0157 }  //namespace container {
0158 }  //namespace boost {
0159 
0160 #include <boost/container/detail/config_end.hpp>
0161 
0162 #endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP)