diff --git a/include/boost/interprocess/detail/in_place_interface.hpp b/include/boost/interprocess/detail/in_place_interface.hpp deleted file mode 100644 index 3ca770d..0000000 --- a/include/boost/interprocess/detail/in_place_interface.hpp +++ /dev/null @@ -1,77 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2005-2012. 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/interprocess for documentation. -// -////////////////////////////////////////////////////////////////////////////// - -#ifndef BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP -#define BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP - -#ifndef BOOST_CONFIG_HPP -# include -#endif -# -#if defined(BOOST_HAS_PRAGMA_ONCE) -# pragma once -#endif - -#include -#include -#include -#include //alignment_of, aligned_storage -#include //typeid - -//!\file -//!Describes an abstract interface for placement construction and destruction. - -namespace boost { -namespace interprocess { -namespace ipcdetail { - -struct in_place_interface -{ - in_place_interface(std::size_t alignm, std::size_t sz, const char *tname) - : alignment(alignm), size(sz), type_name(tname) - {} - - const std::size_t alignment; - const std::size_t size; - const char * const type_name; - - virtual void construct_n(void *mem, std::size_t num) = 0; - virtual void destroy_n(void *mem, std::size_t num) = 0; - virtual ~in_place_interface(){} -}; - -template -struct placement_destroy : public in_place_interface -{ - placement_destroy() - : in_place_interface(::boost::container::dtl::alignment_of::value, sizeof(T), typeid(T).name()) - {} - - virtual void destroy_n(void *mem, std::size_t num) BOOST_OVERRIDE - { - T* memory = static_cast(mem); - for(std::size_t destroyed = 0; destroyed < num; ++destroyed) - (memory++)->~T(); - } - - virtual void construct_n(void *, std::size_t) BOOST_OVERRIDE {} - - private: - void destroy(void *mem) - { static_cast(mem)->~T(); } -}; - -} -} -} //namespace boost { namespace interprocess { namespace ipcdetail { - -#include - -#endif //#ifndef BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP diff --git a/include/boost/interprocess/detail/named_proxy.hpp b/include/boost/interprocess/detail/named_proxy.hpp index 62a94b2..8d6bae4 100644 --- a/include/boost/interprocess/detail/named_proxy.hpp +++ b/include/boost/interprocess/detail/named_proxy.hpp @@ -23,7 +23,6 @@ #include // interprocess/detail -#include #include #include #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING @@ -43,11 +42,31 @@ namespace boost { namespace interprocess { namespace ipcdetail { +template +struct placement_destroy +{ + placement_destroy() + {} + + virtual void destroy_n(void *mem, std::size_t num) + { + T* memory = static_cast(mem); + for(std::size_t destroyed = 0; destroyed < num; ++destroyed) + (memory++)->~T(); + } + + private: + void destroy(void *mem) + { static_cast(mem)->~T(); } +}; + + #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING template struct CtorArgN : public placement_destroy { + typedef T object_type; typedef bool_ IsIterator; typedef CtorArgN self_t; typedef typename build_number_seq::type index_tuple_t; @@ -64,7 +83,7 @@ struct CtorArgN : public placement_destroy : args_(args...) {} - virtual void construct_n(void *mem, std::size_t num) BOOST_OVERRIDE + virtual void construct_n(void *mem, std::size_t num) { std::size_t constructed = 0; BOOST_INTERPROCESS_TRY{ @@ -133,8 +152,7 @@ class named_proxy { CtorArgN &&ctor_obj = CtorArgN (boost::forward(args)...); - return mp_mngr->template - generic_construct(mp_name, m_num, m_find, m_dothrow, ctor_obj); + return mp_mngr->generic_construct(ctor_obj, mp_name, m_num, m_find, m_dothrow); } //This operator allows --> named_new("Name")[3]; <-- syntax @@ -149,12 +167,13 @@ class named_proxy template \ struct CtorArg##N : placement_destroy\ {\ + typedef T object_type;\ typedef CtorArg##N self_t;\ \ CtorArg##N ( BOOST_MOVE_UREF##N )\ BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ \ - virtual void construct_n(void *mem, std::size_t num) BOOST_OVERRIDE\ + virtual void construct_n(void *mem, std::size_t num)\ {\ std::size_t constructed = 0;\ BOOST_INTERPROCESS_TRY{\ @@ -181,6 +200,7 @@ BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CTORARGN) template \ struct CtorIt##N : public placement_destroy\ {\ + typedef T object_type;\ typedef CtorIt##N self_t;\ \ self_t& operator++()\ @@ -191,7 +211,7 @@ struct CtorIt##N : public placement_destroy\ CtorIt##N ( BOOST_MOVE_VAL##N )\ BOOST_MOVE_COLON##N BOOST_MOVE_VAL_INIT##N{}\ \ - virtual void construct_n(void *mem, std::size_t num) BOOST_OVERRIDE\ + virtual void construct_n(void *mem, std::size_t num)\ {\ std::size_t constructed = 0;\ BOOST_INTERPROCESS_TRY{\ @@ -246,7 +266,7 @@ class named_proxy , CtorArg##N \ >::type ctor_obj_t;\ ctor_obj_t ctor_obj = ctor_obj_t( BOOST_MOVE_FWD##N );\ - return mp_mngr->template generic_construct(mp_name, m_num, m_find, m_dothrow, ctor_obj);\ + return mp_mngr->generic_construct(ctor_obj, mp_name, m_num, m_find, m_dothrow);\ }\ // BOOST_MOVE_ITERATE_0TO9(BOOST_INTERPROCESS_NAMED_PROXY_CALL_OPERATOR) @@ -264,8 +284,7 @@ class named_proxy // ctor_obj_t; // ctor_obj_t ctor_obj(p1, p2); // - // return mp_mngr->template generic_construct - // (mp_name, m_num, m_find, m_dothrow, ctor_obj); + // return mp_mngr->(ctor_obj, mp_name, m_num, m_find, m_dothrow); // } // ////////////////////////////////////////////////////////////////////////// diff --git a/include/boost/interprocess/detail/segment_manager_helper.hpp b/include/boost/interprocess/detail/segment_manager_helper.hpp index 23e99cd..72b4a38 100644 --- a/include/boost/interprocess/detail/segment_manager_helper.hpp +++ b/include/boost/interprocess/detail/segment_manager_helper.hpp @@ -27,7 +27,6 @@ // interprocess/detail #include #include -#include // container/detail #include //alignment_of #include @@ -41,9 +40,6 @@ // std #include //std::size_t -//!\file -//!Describes the object placed in a memory segment that provides -//!named object allocation capabilities. namespace boost{ namespace interprocess{ @@ -95,10 +91,6 @@ struct block_header , m_alloc_type_sizeof_char( (unsigned char)((al_type << 5u) | ((unsigned char)szof_char & 0x1F)) ) {}; - template - block_header &operator= (const T& ) - { return *this; } - size_type total_size() const { if(alloc_type() != anonymous_type){ @@ -169,18 +161,17 @@ struct block_header template static block_header *block_header_from_value(T *value) - { return block_header_from_value(value, sizeof(T), ::boost::container::dtl::alignment_of::value); } - - static block_header *block_header_from_value(const void *value, std::size_t sz, std::size_t algn) { - block_header * hdr = + // BOOST_ASSERT(is_ptr_aligned(value, algn)); + const std::size_t algn = ::boost::container::dtl::alignment_of::value; + block_header* hdr = const_cast - (move_detail::force_ptr(reinterpret_cast(value) - - get_rounded_size(sizeof(block_header), algn))); - (void)sz; + (move_detail::force_ptr(reinterpret_cast(value) - + get_rounded_size(sizeof(block_header), algn))); + //Some sanity checks BOOST_ASSERT(hdr->m_value_alignment == algn); - BOOST_ASSERT(hdr->m_value_bytes % sz == 0); + BOOST_ASSERT(hdr->m_value_bytes % sizeof(T) == 0); return hdr; } diff --git a/include/boost/interprocess/segment_manager.hpp b/include/boost/interprocess/segment_manager.hpp index c2c417a..771207e 100644 --- a/include/boost/interprocess/segment_manager.hpp +++ b/include/boost/interprocess/segment_manager.hpp @@ -268,62 +268,6 @@ class segment_manager_base //!Returns the size of the buffer previously allocated pointed by ptr size_type size(const void *ptr) const { return MemoryAlgorithm::size(ptr); } - - #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) - protected: - void * prot_anonymous_construct - (size_type num, bool dothrow, ipcdetail::in_place_interface &table) - { - typedef ipcdetail::block_header block_header_t; - block_header_t block_info ( size_type(table.size*num) - , size_type(table.alignment) - , anonymous_type - , 1 - , 0); - - //Check if there is enough memory - void *ptr_struct = this->allocate_aligned(block_info.total_size(), table.alignment, nothrow<>::get()); - if(!ptr_struct){ - return ipcdetail::null_or_bad_alloc(dothrow); - } - - //Build scoped ptr to avoid leaks with constructor exception - ipcdetail::mem_algo_deallocator mem(ptr_struct, *this); - - //Now construct the header - block_header_t * hdr = ::new(ptr_struct, boost_container_new_t()) block_header_t(block_info); - void *ptr = 0; //avoid gcc warning - ptr = hdr->value(); - - //Now call constructors - table.construct_n(ptr, num); - - //All constructors successful, disable rollback - mem.release(); - return ptr; - } - - //!Calls the destructor and makes an anonymous deallocate - void prot_anonymous_destroy(const void *object, ipcdetail::in_place_interface &table) - { - - //Get control data from associated with this object - typedef ipcdetail::block_header block_header_t; - block_header_t *ctrl_data = block_header_t::block_header_from_value(object, table.size, table.alignment); - - //------------------------------- - //scoped_lock guard(m_header); - //------------------------------- - - //This is not an anonymous object, the pointer is wrong! - BOOST_ASSERT(ctrl_data->alloc_type() == anonymous_type); - - //Call destructors and free memory - //Build scoped ptr to avoid leaks with destructor exception - table.destroy_n(const_cast(object), ctrl_data->m_value_bytes/table.size); - this->deallocate(ctrl_data); - } - #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED }; //!This object is placed in the beginning of memory segment and @@ -533,15 +477,14 @@ class segment_manager bool destroy(char_ptr_holder_t name) { BOOST_ASSERT(!name.is_anonymous()); - ipcdetail::placement_destroy dtor; if(name.is_unique()){ - return this->priv_generic_named_destroy - ( typeid(T).name(), m_header.m_unique_index , dtor, is_intrusive_t()); + return this->priv_generic_named_destroy + ( typeid(T).name(), m_header.m_unique_index, is_intrusive_t()); } else{ - return this->priv_generic_named_destroy - ( name.get(), m_header.m_named_index, dtor, is_intrusive_t()); + return this->priv_generic_named_destroy + ( name.get(), m_header.m_named_index, is_intrusive_t()); } } @@ -550,10 +493,7 @@ class segment_manager template void destroy_ptr(const T *p) { - //If T is void transform it to char - typedef typename ipcdetail::char_if_void::type data_t; - ipcdetail::placement_destroy dtor; - priv_destroy_ptr(p, dtor); + priv_destroy_ptr(p); } //!Returns the name of an object created with construct/find_or_construct @@ -699,15 +639,27 @@ class segment_manager //!Generic named/anonymous new function. Offers all the possibilities, //!such as throwing, search before creating, and the constructor is //!encapsulated in an object function. - template - T *generic_construct(const CharType *name, - size_type num, - bool try2find, - bool dothrow, - ipcdetail::in_place_interface &table) + template + typename Proxy::object_type * generic_construct + (Proxy& pr, const CharType *name, size_type num, bool try2find, bool dothrow) { - return static_cast - (priv_generic_construct(name, num, try2find, dothrow, table)); + typedef typename Proxy::object_type object_type; + + //Security overflow check + if(num > ((size_type)-1)/sizeof(object_type)){ + return ipcdetail::null_or_bad_alloc(dothrow); + } + if(name == 0){ + return this->priv_anonymous_construct(pr, num, dothrow); + } + else if(name == reinterpret_cast(-1)){ + return this->priv_generic_named_construct + (pr, unique_type, typeid(object_type).name(), num, try2find, dothrow, m_header.m_unique_index, is_intrusive_t()); + } + else{ + return this->priv_generic_named_construct + (pr, named_type, name, num, try2find, dothrow, m_header.m_named_index, is_intrusive_t()); + } } private: @@ -719,15 +671,14 @@ class segment_manager { //The name can't be null, no anonymous object can be found by name BOOST_ASSERT(name != 0); - ipcdetail::placement_destroy table; size_type sz; void *ret; if(name == reinterpret_cast(-1)){ - ret = priv_generic_find (typeid(T).name(), m_header.m_unique_index, table, sz, is_intrusive_t(), lock); + ret = priv_generic_find(typeid(T).name(), m_header.m_unique_index, sz, is_intrusive_t(), lock); } else{ - ret = priv_generic_find (name, m_header.m_named_index, table, sz, is_intrusive_t(), lock); + ret = priv_generic_find(name, m_header.m_named_index, sz, is_intrusive_t(), lock); } return std::pair(static_cast(ret), sz); } @@ -736,52 +687,86 @@ class segment_manager //!and the object count. On failure the first member of the //!returned pair is 0. template - std::pair priv_find_impl (const ipcdetail::unique_instance_t* name, bool lock) + std::pair priv_find_impl (const ipcdetail::unique_instance_t*, bool lock) { - ipcdetail::placement_destroy table; size_type size; - void *ret = priv_generic_find(name, m_header.m_unique_index, table, size, is_intrusive_t(), lock); + void *ret = priv_generic_find(typeid(T).name(), m_header.m_unique_index, size, is_intrusive_t(), lock); return std::pair(static_cast(ret), size); } - void *priv_generic_construct - (const CharType *name, size_type num, bool try2find, bool dothrow, ipcdetail::in_place_interface &table) + + template + typename Proxy::object_type * priv_anonymous_construct(Proxy pr, size_type num, bool dothrow) { - void *ret; - //Security overflow check - if(num > ((std::size_t)-1)/table.size){ - return ipcdetail::null_or_bad_alloc(dothrow); + typedef typename Proxy::object_type object_type; + BOOST_CONSTEXPR_OR_CONST std::size_t t_alignment = boost::move_detail::alignment_of::value; + block_header_t block_info ( size_type(sizeof(object_type)*num) + , size_type(t_alignment) + , anonymous_type + , 1 + , 0); + + //Check if there is enough memory + void *ptr_struct = this->allocate(block_info.total_size(), nothrow<>::get()); + if(!ptr_struct){ + return ipcdetail::null_or_bad_alloc(dothrow); } - if(name == 0){ - ret = this->prot_anonymous_construct(num, dothrow, table); - } - else if(name == reinterpret_cast(-1)){ - ret = this->priv_generic_named_construct - (unique_type, table.type_name, num, try2find, dothrow, table, m_header.m_unique_index, is_intrusive_t()); - } - else{ - ret = this->priv_generic_named_construct - (named_type, name, num, try2find, dothrow, table, m_header.m_named_index, is_intrusive_t()); - } - return ret; + + //Build scoped ptr to avoid leaks with constructor exception + ipcdetail::mem_algo_deallocator mem + (ptr_struct, *static_cast(this)); + + //Now construct the header + block_header_t * hdr = ::new(ptr_struct, boost_container_new_t()) block_header_t(block_info); + void *ptr = 0; //avoid gcc warning + ptr = hdr->value(); + + //Now call constructors + pr.construct_n(ptr, num); + + //All constructors successful, disable rollback + mem.release(); + return static_cast(ptr); } - void priv_destroy_ptr(const void *ptr, ipcdetail::in_place_interface &dtor) + //!Calls the destructor and makes an anonymous deallocate + template + void priv_anonymous_destroy(const T *object) { - block_header_t *ctrl_data = block_header_t::block_header_from_value(ptr, dtor.size, dtor.alignment); + + //Get control data from associated with this object + block_header_t *ctrl_data = block_header_t::block_header_from_value(object); + + //------------------------------- + //scoped_lock guard(m_header); + //------------------------------- + + //This is not an anonymous object, the pointer is wrong! + BOOST_ASSERT(ctrl_data->alloc_type() == anonymous_type); + + //Call destructors and free memory + //Build scoped ptr to avoid leaks with destructor exception + priv_destroy_n(object, ctrl_data->m_value_bytes/sizeof(T)); + this->deallocate(ctrl_data); + } + + template + void priv_destroy_ptr(const T *ptr) + { + block_header_t *ctrl_data = block_header_t::block_header_from_value(ptr); switch(ctrl_data->alloc_type()){ case anonymous_type: - this->prot_anonymous_destroy(ptr, dtor); + this->priv_anonymous_destroy(ptr); break; case named_type: - this->priv_generic_named_destroy - (ctrl_data, m_header.m_named_index, dtor, is_node_index_t()); + this->priv_generic_named_destroy + (ctrl_data, m_header.m_named_index, is_node_index_t()); break; case unique_type: - this->priv_generic_named_destroy - (ctrl_data, m_header.m_unique_index, dtor, is_node_index_t()); + this->priv_generic_named_destroy + (ctrl_data, m_header.m_unique_index, is_node_index_t()); break; default: @@ -791,6 +776,13 @@ class segment_manager } } + template + static void priv_destroy_n(T* memory, std::size_t num) + { + for (std::size_t destroyed = 0; destroyed < num; ++destroyed) + (memory++)->~T(); + } + //!Returns the name of an object created with construct/find_or_construct //!functions. Does not throw static const CharType *priv_get_instance_name(block_header_t *ctrl_data) @@ -832,11 +824,10 @@ class segment_manager return sizeof(segment_manager) - sizeof(segment_manager_base_t); } - template - void *priv_generic_find + template + T *priv_generic_find (const CharT* name, IndexType > &index, - ipcdetail::in_place_interface &table, size_type &length, ipcdetail::true_ is_intrusive, bool use_lock) { (void)is_intrusive; @@ -861,19 +852,18 @@ class segment_manager block_header_t *ctrl_data = it->get_block_header(); //Sanity check - BOOST_ASSERT((ctrl_data->m_value_bytes % table.size) == 0); + BOOST_ASSERT((ctrl_data->m_value_bytes % sizeof(T)) == 0); BOOST_ASSERT(ctrl_data->sizeof_char() == sizeof(CharT)); ret_ptr = ctrl_data->value(); - length = ctrl_data->m_value_bytes/table.size; + length = ctrl_data->m_value_bytes/ sizeof(T); } - return ret_ptr; + return static_cast(ret_ptr); } - template - void *priv_generic_find + template + T *priv_generic_find (const CharT* name, IndexType > &index, - ipcdetail::in_place_interface &table, size_type &length, ipcdetail::false_ is_intrusive, bool use_lock) { (void)is_intrusive; @@ -898,43 +888,42 @@ class segment_manager (ipcdetail::to_raw_pointer(it->second.m_ptr)); //Sanity check - BOOST_ASSERT((ctrl_data->m_value_bytes % table.size) == 0); + BOOST_ASSERT((ctrl_data->m_value_bytes % sizeof(T)) == 0); BOOST_ASSERT(ctrl_data->sizeof_char() == sizeof(CharT)); ret_ptr = ctrl_data->value(); - length = ctrl_data->m_value_bytes/table.size; + length = ctrl_data->m_value_bytes/sizeof(T); } - return ret_ptr; + return static_cast(ret_ptr); } - template + template bool priv_generic_named_destroy - (block_header_t *block_header, - IndexType > &index, - ipcdetail::in_place_interface &table, ipcdetail::true_ is_node_index) + (block_header_t *block_header + ,IndexType > &index + ,ipcdetail::true_ is_node_index) { (void)is_node_index; typedef typename IndexType >::iterator index_it; index_it *ihdr = block_header_t::template to_first_header(block_header); - return this->priv_generic_named_destroy_impl(*ihdr, index, table); + return this->priv_generic_named_destroy_impl(*ihdr, index); } - template + template bool priv_generic_named_destroy - (block_header_t *block_header, - IndexType > &index, - ipcdetail::in_place_interface &table, - ipcdetail::false_ is_node_index) + (block_header_t *block_header + ,IndexType > &index + ,ipcdetail::false_ is_node_index) { (void)is_node_index; CharT *name = static_cast(block_header->template name()); - return this->priv_generic_named_destroy(name, index, table, is_intrusive_t()); + return this->priv_generic_named_destroy(name, index, is_intrusive_t()); } - template + template bool priv_generic_named_destroy(const CharT *name, IndexType > &index, - ipcdetail::in_place_interface &table, ipcdetail::true_ is_intrusive_index) + ipcdetail::true_ is_intrusive_index) { (void)is_intrusive_index; typedef IndexType > index_type_t; @@ -959,30 +948,28 @@ class segment_manager block_header_t *ctrl_data = it->get_block_header(); intrusive_value_type *iv = intrusive_value_type::get_intrusive_value_type(ctrl_data); void *memory = iv; - void *values = ctrl_data->value(); - std::size_t num = ctrl_data->m_value_bytes/table.size; //Sanity check - BOOST_ASSERT((ctrl_data->m_value_bytes % table.size) == 0); + BOOST_ASSERT((ctrl_data->m_value_bytes % sizeof(T)) == 0); BOOST_ASSERT(sizeof(CharT) == ctrl_data->sizeof_char()); //Erase node from index index.erase(it); + //Call destructors and free memory + priv_destroy_n(static_cast(ctrl_data->value()), ctrl_data->m_value_bytes/sizeof(T)); + //Destroy the headers ctrl_data->~block_header_t(); iv->~intrusive_value_type(); - //Call destructors and free memory - table.destroy_n(values, num); this->deallocate(memory); return true; } - template + template bool priv_generic_named_destroy(const CharT *name, IndexType > &index, - ipcdetail::in_place_interface &table, ipcdetail::false_ is_intrusive_index) { (void)is_intrusive_index; @@ -1003,14 +990,13 @@ class segment_manager //BOOST_ASSERT(0); return false; } - return this->priv_generic_named_destroy_impl(it, index, table); + return this->priv_generic_named_destroy_impl(it, index); } - template + template bool priv_generic_named_destroy_impl (const typename IndexType >::iterator &it, - IndexType > &index, - ipcdetail::in_place_interface &table) + IndexType > &index) { typedef IndexType > char_aware_index_type; typedef typename char_aware_index_type::iterator index_it; @@ -1021,22 +1007,16 @@ class segment_manager char *stored_name = static_cast(static_cast(const_cast(it->first.name()))); (void)stored_name; - //Check if the distance between the name pointer and the memory pointer - //is correct (this can detect incorrect type in destruction) - std::size_t num = ctrl_data->m_value_bytes/table.size; - void *values = ctrl_data->value(); - //Sanity check - BOOST_ASSERT((ctrl_data->m_value_bytes % table.size) == 0); - BOOST_ASSERT(static_cast(stored_name) == static_cast(ctrl_data->template name())); + //Sanity checks + BOOST_ASSERT((ctrl_data->m_value_bytes % sizeof(T)) == 0); BOOST_ASSERT(sizeof(CharT) == ctrl_data->sizeof_char()); + //Check if the distance between the name pointer and the memory pointer + BOOST_ASSERT(static_cast(stored_name) == static_cast(ctrl_data->template name())); //Erase node from index index.erase(it); - //Destroy the header - ctrl_data->~block_header_t(); - void *memory; if(is_node_index_t::value){ index_it *ihdr = block_header_t::template @@ -1049,25 +1029,31 @@ class segment_manager } //Call destructors and free memory - table.destroy_n(values, num); + priv_destroy_n(static_cast(ctrl_data->value()), ctrl_data->m_value_bytes/sizeof(T)); + + //Destroy the header + ctrl_data->~block_header_t(); + this->deallocate(memory); return true; } - template - void * priv_generic_named_construct - (unsigned char type, const CharT *name, size_type num, bool try2find, - bool dothrow, ipcdetail::in_place_interface &table, + template + typename Proxy::object_type * priv_generic_named_construct + (Proxy pr, unsigned char type, const CharT *name, size_type num, bool try2find, bool dothrow, IndexType > &index, ipcdetail::true_ is_intrusive) { (void)is_intrusive; - std::size_t namelen = std::char_traits::length(name); - block_header_t block_info ( size_type(table.size*num) - , size_type(table.alignment) - , type - , sizeof(CharT) - , namelen); + typedef typename Proxy::object_type object_type; + std::size_t namelen = std::char_traits::length(name); + BOOST_CONSTEXPR_OR_CONST std::size_t t_alignment = boost::move_detail::alignment_of::value; + + block_header_t block_info ( size_type(sizeof(object_type)*num) + , size_type(t_alignment) + , type + , sizeof(CharT) + , namelen); typedef IndexType > index_type_t; typedef typename index_type_t::iterator index_it; @@ -1110,9 +1096,9 @@ class segment_manager //else return null if(!insert_ret.second){ if(try2find){ - return it->get_block_header()->value(); + return static_cast(it->get_block_header()->value()); } - return ipcdetail::null_or_already_exists(dothrow); + return ipcdetail::null_or_already_exists(dothrow); } //Allocates buffer for name + data, this can throw (it hurts) @@ -1121,7 +1107,7 @@ class segment_manager //Check if there is enough memory if (!buffer_ptr) - return ipcdetail::null_or_bad_alloc(dothrow); + return ipcdetail::null_or_bad_alloc(dothrow); //Now construct the intrusive hook plus the header intrusive_value_type * intrusive_hdr = ::new(buffer_ptr, boost_container_new_t()) intrusive_value_type(); @@ -1156,30 +1142,31 @@ class segment_manager value_eraser v_eraser(index, it); //Construct array, this can throw - table.construct_n(ptr, num); + pr.construct_n(ptr, num); //Release rollbacks since construction was successful v_eraser.release(); mem.release(); - return ptr; + return static_cast(ptr); } //!Generic named new function for //!named functions - template - void * priv_generic_named_construct - (unsigned char type, const CharT *name, size_type num, bool try2find, bool dothrow, - ipcdetail::in_place_interface &table, + template + typename Proxy::object_type * priv_generic_named_construct + (Proxy pr, unsigned char type, const CharT *name, size_type num, bool try2find, bool dothrow, IndexType > &index, ipcdetail::false_ is_intrusive) { (void)is_intrusive; + typedef typename Proxy::object_type object_type; std::size_t namelen = std::char_traits::length(name); + BOOST_CONSTEXPR_OR_CONST std::size_t t_alignment = boost::move_detail::alignment_of::value; - block_header_t block_info ( size_type(table.size*num) - , size_type(table.alignment) - , type - , sizeof(CharT) - , namelen); + block_header_t block_info ( size_type(sizeof(object_type)*num) + , size_type(t_alignment) + , type + , sizeof(CharT) + , namelen); typedef IndexType > index_type_t; typedef typename index_type_t::key_type key_type; @@ -1220,9 +1207,9 @@ class segment_manager if(!insert_ret.second){ if(try2find){ block_header_t *hdr = static_cast(ipcdetail::to_raw_pointer(it->second.m_ptr)); - return hdr->value(); + return static_cast(hdr->value()); } - return ipcdetail::null_or_already_exists(dothrow); + return ipcdetail::null_or_already_exists(dothrow); } //Initialize the node value_eraser to erase inserted node //if something goes wrong @@ -1237,7 +1224,7 @@ class segment_manager size_type total_size = block_info.template total_size_with_header(); buffer_ptr = this->allocate(total_size, nothrow<>::get()); if(!buffer_ptr) - return ipcdetail::null_or_bad_alloc(dothrow); + return ipcdetail::null_or_bad_alloc(dothrow); index_it *idr = ::new(buffer_ptr, boost_container_new_t()) index_it(it); hdr = block_header_t::template from_first_header(idr); } @@ -1245,7 +1232,7 @@ class segment_manager buffer_ptr = this->allocate(block_info.total_size(), nothrow<>::get()); //Check if there is enough memory if (!buffer_ptr) - return ipcdetail::null_or_bad_alloc(dothrow); + return ipcdetail::null_or_bad_alloc(dothrow); hdr = static_cast(buffer_ptr); } @@ -1267,14 +1254,14 @@ class segment_manager (buffer_ptr, *static_cast(this)); //Construct array, this can throw - table.construct_n(ptr, num); + pr.construct_n(ptr, num); //All constructors successful, we don't want to release memory mem.release(); //Release node v_eraser since construction was successful v_eraser.release(); - return ptr; + return static_cast(ptr); } private: