////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// #ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP #define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP #if defined(_MSC_VER) # pragma once #endif #include #include #include //allocator_traits #include #include //multiallocation_chain #include //version_type #include //allocation_type #include //integral_constant #include //pointer_traits #include //pair #include //BOOST_TRY namespace boost { namespace container { namespace container_detail { template::value> struct allocator_version_traits { typedef ::boost::container::container_detail::integral_constant alloc_version; typedef typename Allocator::multiallocation_chain multiallocation_chain; typedef typename boost::container::allocator_traits::pointer pointer; typedef typename boost::container::allocator_traits::size_type size_type; //Node allocation interface static pointer allocate_one(Allocator &a) { return a.allocate_one(); } static void deallocate_one(Allocator &a, const pointer &p) { a.deallocate_one(p); } static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m) { return a.allocate_individual(n, m); } static void deallocate_individual(Allocator &a, multiallocation_chain &holder) { a.deallocate_individual(holder); } static std::pair allocation_command(Allocator &a, allocation_type command, size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse) { return a.allocation_command (command, limit_size, preferred_size, received_size, reuse); } }; template struct allocator_version_traits { typedef ::boost::container::container_detail::integral_constant alloc_version; typedef typename boost::container::allocator_traits::pointer pointer; typedef typename boost::container::allocator_traits::size_type size_type; typedef typename boost::container::allocator_traits::value_type value_type; typedef typename boost::intrusive::pointer_traits:: template rebind_pointer::type void_ptr; typedef container_detail::basic_multiallocation_chain multialloc_cached_counted; typedef boost::container::container_detail:: transform_multiallocation_chain < multialloc_cached_counted, value_type> multiallocation_chain; //Node allocation interface static pointer allocate_one(Allocator &a) { return a.allocate(1); } static void deallocate_one(Allocator &a, const pointer &p) { a.deallocate(p, 1); } static void deallocate_individual(Allocator &a, multiallocation_chain &holder) { size_type n = holder.size(); typename multiallocation_chain::iterator it = holder.begin(); while(n--){ pointer p = boost::intrusive::pointer_traits::pointer_to(*it); ++it; a.deallocate(p, 1); } } struct allocate_individual_rollback { allocate_individual_rollback(Allocator &a, multiallocation_chain &chain) : mr_a(a), mp_chain(&chain) {} ~allocate_individual_rollback() { if(mp_chain) allocator_version_traits::deallocate_individual(mr_a, *mp_chain); } void release() { mp_chain = 0; } Allocator &mr_a; multiallocation_chain * mp_chain; }; static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m) { allocate_individual_rollback rollback(a, m); while(n--){ m.push_front(a.allocate(1)); } rollback.release(); } static std::pair allocation_command(Allocator &a, allocation_type command, size_type, size_type preferred_size, size_type &received_size, const pointer &) { std::pair ret(pointer(), false); if(!(command & allocate_new)){ if(!(command & nothrow_allocation)){ throw_logic_error("version 1 allocator without allocate_new flag"); } } else{ received_size = preferred_size; BOOST_TRY{ ret.first = a.allocate(received_size); } BOOST_CATCH(...){ if(!(command & nothrow_allocation)){ BOOST_RETHROW } } BOOST_CATCH_END } return ret; } }; } //namespace container_detail { } //namespace container { } //namespace boost { #include #endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP)