diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index ac63361..f440928 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3839,6 +3839,7 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std * Fixed bugs: * [@https://svn.boost.org/trac/boost/ticket/12190 Boost Trac #12190: ['Intrusive List + Flat Map combination crashes]] + * [@https://svn.boost.org/trac/boost/ticket/12245 Boost Trac #12245: ['bstree uses a shared static size_traits for constant_time_size]] [endsect] diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index 0fb9218..a5f20a7 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -554,18 +554,10 @@ struct bstbase_hack size_traits; - size_traits &sz_traits() - { return s_size_traits; } - - const size_traits &sz_traits() const - { return s_size_traits; } - - static size_traits s_size_traits; + size_traits sz_traits() const + { return size_traits(); } }; -template -detail::size_holder bstbase_hack::s_size_traits; - //This class will template struct bstbase @@ -955,11 +947,7 @@ class bstree_impl ::boost::adl_move_swap(this->comp(), this->comp()); //These can't throw node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr())); - if(constant_time_size){ - size_type backup = this->sz_traits().get_size(); - this->sz_traits().set_size(other.sz_traits().get_size()); - other.sz_traits().set_size(backup); - } + this->sz_traits().swap(other.sz_traits()); } //! Requires: Disposer::operator()(pointer) shouldn't throw. diff --git a/include/boost/intrusive/detail/size_holder.hpp b/include/boost/intrusive/detail/size_holder.hpp index 9802ac3..bd14dc5 100644 --- a/include/boost/intrusive/detail/size_holder.hpp +++ b/include/boost/intrusive/detail/size_holder.hpp @@ -51,6 +51,9 @@ struct size_holder BOOST_INTRUSIVE_FORCEINLINE void decrease(SizeType n) { size_ -= n; } + BOOST_INTRUSIVE_FORCEINLINE void swap(size_holder &other) + { SizeType tmp(size_); size_ = other.size_; other.size_ = tmp; } + SizeType size_; }; @@ -77,6 +80,8 @@ struct size_holder BOOST_INTRUSIVE_FORCEINLINE void decrease(SizeType) {} + + BOOST_INTRUSIVE_FORCEINLINE void swap(size_holder){} }; } //namespace detail{ diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp index f9074c0..4a8e9a8 100644 --- a/include/boost/intrusive/hashtable.hpp +++ b/include/boost/intrusive/hashtable.hpp @@ -119,6 +119,8 @@ struct prime_list_holder static const std::size_t prime_list_size; }; +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + //We only support LLP64(Win64) or LP64(most Unix) data models #ifdef _WIN64 //In 64 bit windows sizeof(size_t) == sizeof(unsigned long long) #define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##ULL @@ -173,6 +175,8 @@ const std::size_t prime_list_holder::prime_list[] = { #undef BOOST_INTRUSIVE_PRIME_C #undef BOOST_INTRUSIVE_64_BIT_SIZE_T +#endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + template const std::size_t prime_list_holder::prime_list_size = sizeof(prime_list)/sizeof(std::size_t); @@ -1243,10 +1247,13 @@ struct hashtable_size_traits_wrapper size_traits size_traits_; - const size_traits &priv_size_traits() const + typedef const size_traits & size_traits_const_t; + typedef size_traits & size_traits_t; + + size_traits_const_t priv_size_traits() const { return size_traits_; } - size_traits &priv_size_traits() + size_traits_t priv_size_traits() { return size_traits_; } }; @@ -1265,18 +1272,13 @@ struct hashtable_size_traits_wrapper typedef detail::size_holder< false, SizeType> size_traits; - const size_traits &priv_size_traits() const - { return size_traits_; } + typedef size_traits size_traits_const_t; + typedef size_traits size_traits_t; - size_traits &priv_size_traits() - { return size_traits_; } - - static size_traits size_traits_; + BOOST_INTRUSIVE_FORCEINLINE size_traits priv_size_traits() const + { return size_traits(); } }; -template -detail::size_holder< false, SizeType > hashtable_size_traits_wrapper::size_traits_; - //hashdata_internal //Stores bucket_hash_equal_t and split_traits template @@ -1360,10 +1362,10 @@ struct hashdata_internal : internal_type(val_traits, ::boost::forward(b_traits), h, e) {} - split_traits &priv_split_traits() + BOOST_INTRUSIVE_FORCEINLINE typename internal_type::size_traits_t priv_split_traits() { return this->priv_size_traits(); } - const split_traits &priv_split_traits() const + BOOST_INTRUSIVE_FORCEINLINE typename internal_type::size_traits_const_t priv_split_traits() const { return this->priv_size_traits(); } ~hashdata_internal() @@ -1790,15 +1792,10 @@ class hashtable_impl { this->priv_swap_cache(x); x.priv_initialize_cache(); - if(constant_time_size){ - this->priv_size_traits().set_size(size_type(0)); - this->priv_size_traits().set_size(x.priv_size_traits().get_size()); - x.priv_size_traits().set_size(size_type(0)); - } - if(incremental){ - this->priv_split_traits().set_size(x.priv_split_traits().get_size()); - x.priv_split_traits().set_size(size_type(0)); - } + this->priv_size_traits().set_size(x.priv_size_traits().get_size()); + x.priv_size_traits().set_size(size_type(0)); + this->priv_split_traits().set_size(x.priv_split_traits().get_size()); + x.priv_split_traits().set_size(size_type(0)); } //! Effects: to-do @@ -1946,8 +1943,8 @@ class hashtable_impl ::boost::adl_move_swap(this->priv_bucket_traits(), other.priv_bucket_traits()); ::boost::adl_move_swap(this->priv_value_traits(), other.priv_value_traits()); this->priv_swap_cache(other); - ::boost::adl_move_swap(this->priv_size_traits(), other.priv_size_traits()); - ::boost::adl_move_swap(this->priv_split_traits(), other.priv_split_traits()); + this->priv_size_traits().swap(other.priv_size_traits()); + this->priv_split_traits().swap(other.priv_split_traits()); } //! Requires: Disposer::operator()(pointer) shouldn't throw diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index a59734a..a955c44 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -542,11 +542,7 @@ class list_impl void swap(list_impl& other) { node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node()); - if(constant_time_size){ - size_type backup = this->priv_size_traits().get_size(); - this->priv_size_traits().set_size(other.priv_size_traits().get_size()); - other.priv_size_traits().set_size(backup); - } + this->priv_size_traits().swap(other.priv_size_traits()); } //! Effects: Moves backwards all the elements, so that the first diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index cf8da58..5ce9329 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -716,11 +716,7 @@ class slist_impl else{ this->priv_swap_lists(this->get_root_node(), other.get_root_node(), detail::bool_()); } - if(constant_time_size){ - size_type backup = this->priv_size_traits().get_size(); - this->priv_size_traits().set_size(other.priv_size_traits().get_size()); - other.priv_size_traits().set_size(backup); - } + this->priv_size_traits().swap(other.priv_size_traits()); } //! Effects: Moves backwards all the elements, so that the first