diff --git a/include/boost/interprocess/detail/segment_manager_helper.hpp b/include/boost/interprocess/detail/segment_manager_helper.hpp index f3102641..46f872da 100644 --- a/include/boost/interprocess/detail/segment_manager_helper.hpp +++ b/include/boost/interprocess/detail/segment_manager_helper.hpp @@ -144,21 +144,6 @@ struct block_header return get_rounded_size(size_type(sizeof(block_header)), size_type(m_value_alignment)); } - template - bool less_comp(const block_header &b) const - { - return m_num_char < b.m_num_char || - (m_num_char < b.m_num_char && - std::char_traits::compare(name(), b.name(), m_num_char) < 0); - } - - template - bool equal_comp(const block_header &b) const - { - return m_num_char == b.m_num_char && - std::char_traits::compare(name(), b.name(), m_num_char) == 0; - } - template static block_header *block_header_from_value(T *value) { @@ -186,6 +171,10 @@ struct block_header return hdr; } + template + static const block_header *from_first_header(const Header *header) + { return from_first_header(const_cast(header)); } + template static Header *to_first_header(block_header *bheader) { @@ -207,29 +196,17 @@ struct intrusive_compare_key : mp_str(str), m_len(len) {} - const CharT * mp_str; - std::size_t m_len; -}; + const CharT *str() const + { return mp_str; } -template -struct compare_key_impl -{ - typedef typename IndexType::compare_key_type type; -}; + std::size_t len() const + { return m_len; } -template -struct compare_key_impl -{ - typedef typename IndexType::key_type type; + const CharT * mp_str; + std::size_t m_len; }; -template -struct compare_key - : compare_key_impl::value> -{}; - - //!This struct indicates an anonymous object creation //!allocation template @@ -270,26 +247,14 @@ struct intrusive_value_type_impl intrusive_value_type_impl(){} - enum { BlockHdrAlignment = ::boost::container::dtl::alignment_of::value }; + block_header_t *get_block_header() + { return block_header_t::from_first_header(this); } - block_header_t *get_block_header() const - { - return const_cast - (move_detail::force_ptr(reinterpret_cast(this) + - get_rounded_size(size_type(sizeof(*this)), size_type(BlockHdrAlignment)))); - } - - bool operator <(const intrusive_value_type_impl & other) const - { return (this->get_block_header())->template less_comp(*other.get_block_header()); } - - bool operator ==(const intrusive_value_type_impl & other) const - { return (this->get_block_header())->template equal_comp(*other.get_block_header()); } + const block_header_t *get_block_header() const + { return block_header_t::from_first_header(this); } static intrusive_value_type_impl *get_intrusive_value_type(block_header_t *hdr) - { - return move_detail::force_ptr(reinterpret_cast(hdr) - - get_rounded_size(size_type(sizeof(intrusive_value_type_impl)), size_type(BlockHdrAlignment))); - } + { return block_header_t::template to_first_header(hdr); } CharType *name() const { return get_block_header()->template name(); } diff --git a/include/boost/interprocess/indexes/flat_map_index.hpp b/include/boost/interprocess/indexes/flat_map_index.hpp index 8d84323e..72eeec17 100644 --- a/include/boost/interprocess/indexes/flat_map_index.hpp +++ b/include/boost/interprocess/indexes/flat_map_index.hpp @@ -61,29 +61,55 @@ struct flat_map_index_aux template class flat_map_index //Derive class from flat_map specialization - : public flat_map_index_aux::index_t + : private flat_map_index_aux::index_t { #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) typedef flat_map_index_aux index_aux; typedef typename index_aux::index_t base_type; typedef typename index_aux:: segment_manager_base segment_manager_base; + typedef typename base_type::key_type key_type; #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED public: + using base_type::begin; + using base_type::end; + using base_type::size; + using base_type::erase; + using base_type::shrink_to_fit; + using base_type::reserve; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::value_type value_type; + typedef typename MapConfig::compare_key_type compare_key_type; + typedef iterator insert_commit_data; + typedef iterator index_data_t; + //!Constructor. Takes a pointer to the segment manager. Can throw flat_map_index(segment_manager_base *segment_mngr) : base_type(typename index_aux::key_less(), typename index_aux::allocator_type(segment_mngr)) {} - //!This reserves memory to optimize the insertion of n elements in the index - void reserve(typename segment_manager_base::size_type n) - { base_type::reserve(n); } + std::pair insert_check + (const compare_key_type& key, insert_commit_data&) + { + std::pair r; + r.first = this->base_type::find(key_type(key.str(), key.len())); + r.second = r.first == this->base_type::end(); + return r; + } + + iterator insert_commit + (const compare_key_type &k, void *context, index_data_t&, insert_commit_data& ) + { + //Now commit the insertion using previous context data + typedef typename base_type::mapped_type mapped_type; + return this->base_type::insert(value_type(key_type(k.str(), k.len()), mapped_type(context))).first; + } - //!This frees all unnecessary memory - void shrink_to_fit() - { base_type::shrink_to_fit(); } + iterator find(const compare_key_type& k) + { return this->base_type::find(key_type(k.str(), k.len())); } }; }} //namespace boost { namespace interprocess diff --git a/include/boost/interprocess/indexes/iset_index.hpp b/include/boost/interprocess/indexes/iset_index.hpp index 26e3c74e..01e68288 100644 --- a/include/boost/interprocess/indexes/iset_index.hpp +++ b/include/boost/interprocess/indexes/iset_index.hpp @@ -51,13 +51,48 @@ struct iset_index_aux < bi::void_pointer , bi::optimize_size >::type derivation_hook; - + typedef typename MapConfig::char_type char_type; typedef typename MapConfig::template intrusive_value_type::type value_type; + + typedef typename MapConfig::compare_key_type compare_key_type; + + struct less_function + { + bool operator()(const compare_key_type&i, const value_type &b) const + { + std::size_t blen = b.name_length(); + return (i.m_len < blen) || + (i.m_len == blen && + std::char_traits::compare + (i.mp_str, b.name(), i.m_len) < 0); + } + + bool operator()(const value_type &b, const compare_key_type&i) const + { + std::size_t blen = b.name_length(); + return (blen < i.m_len) || + (blen == i.m_len && + std::char_traits::compare + (b.name(), i.mp_str, i.m_len) < 0); + } + + bool operator()(const value_type& a, const value_type& b) const + { + std::size_t alen = a.name_length(); + std::size_t blen = b.name_length(); + return (alen < blen) || + (alen == blen && + std::char_traits::compare + (a.name(), b.name(), alen) < 0); + } + }; + typedef std::less value_compare; typedef typename bi::make_set < value_type , bi::base_hook + , bi::compare >::type index_t; }; #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED @@ -68,12 +103,13 @@ struct iset_index_aux template class iset_index //Derive class from map specialization - : public iset_index_aux::index_t + : private iset_index_aux::index_t { #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) typedef iset_index_aux index_aux; typedef typename index_aux::index_t index_type; typedef typename MapConfig::char_type char_type; + typedef typename index_aux::less_function less_function; #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED public: @@ -82,35 +118,15 @@ class iset_index typedef typename index_type::insert_commit_data insert_commit_data; typedef typename index_type::value_type value_type; typedef typename MapConfig::compare_key_type compare_key_type; - - #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) - private: - - struct intrusive_key_value_less - { - bool operator()(const compare_key_type&i, const value_type &b) const - { - std::size_t blen = b.name_length(); - return (i.m_len < blen) || - (i.m_len == blen && - std::char_traits::compare - (i.mp_str, b.name(), i.m_len) < 0); - } - - bool operator()(const value_type &b, const compare_key_type&i) const - { - std::size_t blen = b.name_length(); - return (blen < i.m_len) || - (blen == i.m_len && - std::char_traits::compare - (b.name(), i.mp_str, i.m_len) < 0); - } - }; - - #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + typedef value_type index_data_t; public: + using index_type::begin; + using index_type::end; + using index_type::size; + using index_type::erase; + //!Constructor. Takes a pointer to the //!segment manager. Can throw iset_index(typename MapConfig::segment_manager_base *) @@ -127,14 +143,18 @@ class iset_index { /*Does nothing, this intrusive index does not allocate memory;*/ } iterator find(const compare_key_type&key) - { return index_type::find(key, intrusive_key_value_less()); } + { return index_type::find(key, less_function()); } const_iterator find(const compare_key_type&key) const - { return index_type::find(key, intrusive_key_value_less()); } + { return index_type::find(key, less_function()); } std::pairinsert_check - (const compare_key_type&key, insert_commit_data &commit_data) - { return index_type::insert_check(key, intrusive_key_value_less(), commit_data); } + (const compare_key_type &key, insert_commit_data &commit_data) + { return index_type::insert_check(key, less_function(), commit_data); } + + iterator insert_commit + (const compare_key_type &, void*, index_data_t&v, insert_commit_data& commit_data) + { return index_type::insert_commit(v, commit_data); } }; #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) diff --git a/include/boost/interprocess/indexes/iunordered_set_index.hpp b/include/boost/interprocess/indexes/iunordered_set_index.hpp index 2396261d..fa0ddba9 100644 --- a/include/boost/interprocess/indexes/iunordered_set_index.hpp +++ b/include/boost/interprocess/indexes/iunordered_set_index.hpp @@ -146,7 +146,7 @@ template class iunordered_set_index //Derive class from map specialization : private iunordered_set_index_aux::allocator_holder - , public iunordered_set_index_aux::index_t + , private iunordered_set_index_aux::index_t { #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) typedef iunordered_set_index_aux index_aux; @@ -172,6 +172,7 @@ class iunordered_set_index typedef typename index_type::bucket_traits bucket_traits; typedef typename index_type::size_type size_type; typedef typename index_type::difference_type difference_type; + typedef value_type index_data_t; #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) private: @@ -260,6 +261,11 @@ class iunordered_set_index #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED public: + using index_type::begin; + using index_type::end; + using index_type::size; + using index_type::erase; + //!Constructor. Takes a pointer to the //!segment manager. Can throw iunordered_set_index(segment_manager_base *mngr) @@ -346,7 +352,8 @@ class iunordered_set_index (const compare_key_type&key, insert_commit_data &commit_data) { return index_type::insert_check(key, hash_function(), equal_function(), commit_data); } - iterator insert_commit(value_type &val, insert_commit_data &commit_data) + iterator insert_commit + (const compare_key_type &, void *, index_data_t &val, insert_commit_data& commit_data) { iterator it = index_type::insert_commit(val, commit_data); size_type cur_size = this->size(); diff --git a/include/boost/interprocess/indexes/map_index.hpp b/include/boost/interprocess/indexes/map_index.hpp index 2b3c7415..75eea525 100644 --- a/include/boost/interprocess/indexes/map_index.hpp +++ b/include/boost/interprocess/indexes/map_index.hpp @@ -62,16 +62,29 @@ struct map_index_aux template class map_index //Derive class from map specialization - : public ipcdetail::map_index_aux::index_t + : private ipcdetail::map_index_aux::index_t { #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) - typedef ipcdetail::map_index_aux index_aux; - typedef typename index_aux::index_t base_type; + typedef ipcdetail::map_index_aux index_aux; + typedef typename index_aux::index_t base_type; typedef typename MapConfig:: - segment_manager_base segment_manager_base; + segment_manager_base segment_manager_base; + typedef typename base_type::key_type key_type; + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED public: + using base_type::begin; + using base_type::end; + using base_type::size; + using base_type::erase; + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::value_type value_type; + typedef typename MapConfig::compare_key_type compare_key_type; + typedef iterator insert_commit_data; + typedef iterator index_data_t; + //!Constructor. Takes a pointer to the //!segment manager. Can throw map_index(segment_manager_base *segment_mngr) @@ -87,6 +100,27 @@ class map_index //!unused memory. void shrink_to_fit() { base_type::get_stored_allocator().deallocate_free_blocks(); } + + std::pair insert_check + (const compare_key_type& key, insert_commit_data& ) + { + std::pair r; + r.first = this->base_type::find(key_type(key.str(), key.len())); + r.second = r.first == this->base_type::end(); + return r; + } + + iterator insert_commit + (const compare_key_type &k, void *context, index_data_t &index_data, insert_commit_data& ) + { + //Now commit the insertion using previous context data + typedef typename base_type::mapped_type mapped_type; + iterator it = this->base_type::insert(value_type(key_type(k.str(), k.len()), mapped_type(context))).first; + return (index_data = it); + } + + iterator find(const compare_key_type& k) + { return this->base_type::find(key_type(k.str(), k.len())); } }; #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) diff --git a/include/boost/interprocess/segment_manager.hpp b/include/boost/interprocess/segment_manager.hpp index f18f1b4a..3f16a237 100644 --- a/include/boost/interprocess/segment_manager.hpp +++ b/include/boost/interprocess/segment_manager.hpp @@ -479,12 +479,10 @@ class segment_manager BOOST_ASSERT(!name.is_anonymous()); if(name.is_unique()){ - return this->priv_generic_named_destroy - ( typeid(T).name(), m_header.m_unique_index, is_intrusive_t()); + return this->priv_generic_named_destroy(typeid(T).name(), m_header.m_unique_index); } else{ - return this->priv_generic_named_destroy - ( name.get(), m_header.m_named_index, is_intrusive_t()); + return this->priv_generic_named_destroy(name.get(), m_header.m_named_index); } } @@ -654,11 +652,11 @@ class segment_manager } 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()); + (pr, unique_type, typeid(object_type).name(), num, try2find, dothrow, m_header.m_unique_index); } else{ return this->priv_generic_named_construct - (pr, named_type, name, num, try2find, dothrow, m_header.m_named_index, is_intrusive_t()); + (pr, named_type, name, num, try2find, dothrow, m_header.m_named_index); } } @@ -830,9 +828,10 @@ class segment_manager IndexType > &index, size_type &length, bool use_lock) { - typedef IndexType > index_type_t; - typedef typename index_type_t::iterator index_it; - typedef typename ipcdetail::compare_key::type compare_key_t; + typedef IndexType > index_t; + typedef typename index_t::iterator index_it; + typedef typename index_t::compare_key_type compare_key_t; //------------------------------- scoped_lock guard(priv_get_lock(use_lock)); @@ -866,10 +865,11 @@ class segment_manager ,ipcdetail::true_ is_node_index) { (void)is_node_index; - typedef typename IndexType >::iterator index_it; + typedef IndexType > index_t; + typedef typename index_t::index_data_t index_data_t; - index_it *ihdr = block_header_t::template to_first_header(block_header); - return this->priv_generic_named_destroy_impl(*ihdr, index); + index_data_t *si = priv_index_header_from_block(block_header, is_intrusive_t()); + return this->priv_generic_named_destroy_impl(*si, index); } template @@ -880,73 +880,24 @@ class segment_manager { (void)is_node_index; CharT *name = static_cast(block_header->template name()); - return this->priv_generic_named_destroy(name, index, is_intrusive_t()); + return this->priv_generic_named_destroy(name, index); } template bool priv_generic_named_destroy(const CharT *name, - IndexType > &index, - ipcdetail::true_ is_intrusive) + IndexType > &index) { - (void)is_intrusive; - typedef IndexType > index_type_t; - typedef typename index_type_t::iterator index_it; - typedef typename index_type_t::value_type intrusive_value_type; + typedef IndexType > index_t; + typedef typename index_t::iterator index_it; + typedef typename index_t::compare_key_type compare_key_t; //------------------------------- scoped_lock guard(m_header); //------------------------------- //Find name in index - ipcdetail::intrusive_compare_key key - (name, std::char_traits::length(name)); + compare_key_t key(name, std::char_traits::length(name)); index_it it = index.find(key); - //If not found, return false - if(it == index.end()){ - //This name is not present in the index, wrong pointer or name! - //BOOST_ASSERT(0); - return false; - } - - block_header_t *ctrl_data = priv_block_header_from_it(it, is_intrusive); - intrusive_value_type *iv = intrusive_value_type::get_intrusive_value_type(ctrl_data); - void *memory = iv; - - //Sanity check - 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(); - - this->deallocate(memory); - return true; - } - - template - bool priv_generic_named_destroy(const CharT *name, - IndexType > &index, - ipcdetail::false_ is_intrusive_index) - { - (void)is_intrusive_index; - typedef IndexType > char_aware_index_type; - typedef typename char_aware_index_type::iterator index_it; - typedef typename char_aware_index_type::key_type key_type; - - //------------------------------- - scoped_lock guard(m_header); - //------------------------------- - //Try to find the name in the index - index_it it = index.find(key_type (name, - std::char_traits::length(name))); - //If not found, return false if(it == index.end()){ //This name is not present in the index, wrong pointer or name! @@ -961,29 +912,23 @@ class segment_manager (const typename IndexType >::iterator &it, IndexType > &index) { - typedef IndexType > char_aware_index_type; - typedef typename char_aware_index_type::iterator index_it; + typedef IndexType > index_t; + typedef typename index_t::index_data_t index_data_t; //Get allocation parameters block_header_t *ctrl_data = priv_block_header_from_it(it, is_intrusive_t()); - char *stored_name = static_cast(static_cast(const_cast(it->first.name()))); - (void)stored_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); void *memory; - BOOST_IF_CONSTEXPR(is_node_index_t::value){ - index_it *ihdr = block_header_t::template - to_first_header(ctrl_data); - ihdr->~index_it(); + BOOST_IF_CONSTEXPR(is_node_index_t::value || is_intrusive_t::value){ + index_data_t*ihdr = priv_index_header_from_block(ctrl_data, is_intrusive_t()); + ihdr->~index_data_t(); memory = ihdr; } else{ @@ -993,7 +938,7 @@ class segment_manager //Call destructors and free memory priv_destroy_n(static_cast(ctrl_data->value()), ctrl_data->m_value_bytes/sizeof(T)); - //Destroy the header + //Destroy the headers ctrl_data->~block_header_t(); this->deallocate(memory); @@ -1003,7 +948,7 @@ class segment_manager template static block_header_t* priv_block_header_from_it(IndexIt it, ipcdetail::true_) //is_intrusive { - return it->get_block_header(); + return block_header_t::from_first_header(&*it); } template @@ -1012,108 +957,17 @@ class segment_manager return static_cast(ipcdetail::to_raw_pointer(it->second.m_ptr)); } - 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) + template + static typename IndexT::index_data_t * priv_index_header_from_block(block_header_t *bh, ipcdetail::true_) //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(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; - - //------------------------------- - scoped_lock guard(m_header); - //------------------------------- - //First, we want to know if the key is already present before - //we allocate any memory, and if the key is not present, we - //want to allocate all memory in a single buffer that will - //contain the name and the user buffer. - index_it existing_it; - bool found = false; - typedef typename index_type_t::value_type value_type; - - typename index_type_t::insert_commit_data commit_data; - BOOST_INTERPROCESS_TRY{ - typedef std::pair index_ib; - ipcdetail::intrusive_compare_key key(name, namelen); - index_ib insert_ret = index.insert_check(key, commit_data); - existing_it = insert_ret.first; - found = !insert_ret.second; - } - //Ignore exceptions - BOOST_INTERPROCESS_CATCH(...){ - if(dothrow) - BOOST_INTERPROCESS_RETHROW - return 0; - } - BOOST_INTERPROCESS_CATCH_END - - //If found and this is find or construct, return data, error otherwise - if(found){ - if(try2find){ - return static_cast(priv_block_header_from_it(existing_it, is_intrusive)->value()); - } - return ipcdetail::null_or_already_exists(dothrow); - } - - //Allocates buffer for name + data, this can throw (it hurts) - void *buffer_ptr = this->allocate - (block_info.template total_size_with_header(), nothrow<>::get()); - - //Check if there is enough memory - if (!buffer_ptr) - return ipcdetail::null_or_bad_alloc(dothrow); - - //Now construct the intrusive hook plus the header - value_type* intrusive_hdr = ::new(buffer_ptr, boost_container_new_t()) value_type(); - block_header_t * hdr = ::new(intrusive_hdr->get_block_header(), boost_container_new_t()) block_header_t(block_info); - void *ptr = hdr->value(); - - //Copy name to memory segment and insert data - CharT *name_ptr = static_cast(hdr->template name()); - std::char_traits::copy(name_ptr, name, namelen+1); - - index_it it; - BOOST_INTERPROCESS_TRY{ - //Now commit the insertion using previous context data - it = index.insert_commit(*intrusive_hdr, commit_data); - } - //Ignore exceptions - BOOST_INTERPROCESS_CATCH(...){ - if(dothrow) - BOOST_INTERPROCESS_RETHROW - return 0; - } - BOOST_INTERPROCESS_CATCH_END - - //Avoid constructions if constructor is trivial - //Build scoped ptr to avoid leaks with constructor exception - ipcdetail::mem_algo_deallocator mem - (buffer_ptr, *static_cast(this)); - - //Initialize the node value_eraser to erase inserted node - //if something goes wrong. This will be executed *before* - //the memory allocation as the intrusive value is built in that - //memory - value_eraser v_eraser(index, it); - - //Construct array, this can throw - pr.construct_n(ptr, num); + return IndexT::index_data_t::get_intrusive_value_type(bh); + } - //Release rollbacks since construction was successful - v_eraser.release(); - mem.release(); - return static_cast(ptr); + template + static typename IndexT::index_data_t * priv_index_header_from_block(block_header_t* bh, ipcdetail::false_) //!is_intrusive + { + return block_header_t::template to_first_header + (bh); } //!Generic named new function for @@ -1121,9 +975,8 @@ class segment_manager 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) + IndexType > &index) { - (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; @@ -1134,8 +987,11 @@ class segment_manager , sizeof(CharT) , namelen); - typedef IndexType > index_type_t; - typedef typename index_type_t::iterator index_it; + typedef IndexType > index_t; + typedef typename index_t::iterator index_it; + typedef typename index_t::compare_key_type compare_key_t; + typedef typename index_t::insert_commit_data commit_data_t; + typedef typename index_t::index_data_t index_data_t; //------------------------------- scoped_lock guard(m_header); @@ -1146,12 +1002,13 @@ class segment_manager //contain the name and the user buffer. index_it existing_it; bool found = false; - typedef typename index_type_t::value_type value_type; + commit_data_t commit_data; BOOST_INTERPROCESS_TRY{ - typedef typename index_type_t::key_type key_type; - existing_it = index.find(key_type(name, namelen)); - found = existing_it != index.end(); + typedef std::pair index_ib; + index_ib insert_ret = index.insert_check(compare_key_t(name, namelen), commit_data); + existing_it = insert_ret.first; + found = !insert_ret.second; } //Ignore exceptions BOOST_INTERPROCESS_CATCH(...){ @@ -1164,7 +1021,7 @@ class segment_manager //If found and this is find or construct, return data, error otherwise if(found){ if(try2find){ - return static_cast(priv_block_header_from_it(existing_it, is_intrusive)->value()); + return static_cast(priv_block_header_from_it(existing_it, is_intrusive_t())->value()); } return ipcdetail::null_or_already_exists(dothrow); } @@ -1174,12 +1031,12 @@ class segment_manager block_header_t * hdr; //Allocate and construct the headers - BOOST_IF_CONSTEXPR(is_node_index_t::value){ - size_type total_size = block_info.template total_size_with_header(); + BOOST_IF_CONSTEXPR(is_node_index_t::value || is_intrusive_t::value){ + 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); - hdr = block_header_t::template from_first_header(static_cast(buffer_ptr)); + hdr = block_header_t::template from_first_header(static_cast(buffer_ptr)); } else{ buffer_ptr = this->allocate(block_info.total_size(), nothrow<>::get()); @@ -1195,7 +1052,7 @@ class segment_manager ipcdetail::mem_algo_deallocator mem (buffer_ptr, *static_cast(this)); - void *ptr = hdr->value(); + void *ptr = hdr->value(); //Copy name to memory segment and insert data CharT *name_ptr = static_cast(hdr->template name()); @@ -1203,12 +1060,13 @@ class segment_manager index_it it; BOOST_INTERPROCESS_TRY{ - //Now commit the insertion using previous context data - typedef typename index_type_t::mapped_type mapped_type; - typedef typename index_type_t::key_type key_type; - it = index.insert(value_type(key_type(name_ptr, namelen), mapped_type(hdr))).first; - BOOST_IF_CONSTEXPR(is_node_index_t::value) { - ::new(buffer_ptr, boost_container_new_t()) index_it(it); + BOOST_IF_CONSTEXPR(is_node_index_t::value || is_intrusive_t::value) { + index_data_t* index_data = ::new(buffer_ptr, boost_container_new_t()) index_data_t(); + it = index.insert_commit(compare_key_t(name_ptr, namelen), hdr, *index_data, commit_data); + } + else{ + index_data_t id; + it = index.insert_commit(compare_key_t(name_ptr, namelen), hdr, id, commit_data); } } //Ignore exceptions @@ -1221,7 +1079,7 @@ class segment_manager //Initialize the node value_eraser to erase inserted node //if something goes wrong - value_eraser v_eraser(index, it); + value_eraser v_eraser(index, it); //Construct array, this can throw pr.construct_n(ptr, num);