diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index a944077..1c13c62 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -74,6 +74,8 @@ class avl_set_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; + static const bool constant_time_size = Config::constant_time_size; + /// @cond private: tree_type tree_; @@ -1264,6 +1266,8 @@ class avl_multiset_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; + static const bool constant_time_size = Config::constant_time_size; + /// @cond private: tree_type tree_; diff --git a/include/boost/intrusive/avltree_algorithms.hpp b/include/boost/intrusive/avltree_algorithms.hpp index a632581..7e0cd2e 100644 --- a/include/boost/intrusive/avltree_algorithms.hpp +++ b/include/boost/intrusive/avltree_algorithms.hpp @@ -104,7 +104,7 @@ class avltree_algorithms static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + return node_ptr(const_cast(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr))); } /// @endcond diff --git a/include/boost/intrusive/circular_slist_algorithms.hpp b/include/boost/intrusive/circular_slist_algorithms.hpp index ae06396..8bb95cd 100644 --- a/include/boost/intrusive/circular_slist_algorithms.hpp +++ b/include/boost/intrusive/circular_slist_algorithms.hpp @@ -63,7 +63,7 @@ class circular_slist_algorithms //! Effects: Constructs an non-used list element, putting the next //! pointer to null: - //! NodeTraits::get_next(this_node) == 0 + //! NodeTraits::get_next(this_node) == 0 //! //! Complexity: Constant //! diff --git a/include/boost/intrusive/derivation_value_traits.hpp b/include/boost/intrusive/derivation_value_traits.hpp index 7b5b013..8711d56 100644 --- a/include/boost/intrusive/derivation_value_traits.hpp +++ b/include/boost/intrusive/derivation_value_traits.hpp @@ -14,6 +14,7 @@ #define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP #include +#include #include namespace boost { @@ -44,10 +45,20 @@ struct derivation_value_traits { return node_ptr(&value); } static pointer to_value_ptr(node_ptr n) - { return pointer(static_cast(detail::get_pointer(n))); } + { +// This still fails in gcc < 4.4 so forget about it +// using ::boost::static_pointer_cast; +// return static_pointer_cast(n)); + return pointer(&static_cast(*n)); + } static const_pointer to_value_ptr(const_node_ptr n) - { return const_pointer(static_cast(detail::get_pointer(n))); } + { +// This still fails in gcc < 4.4 so forget about it +// using ::boost::static_pointer_cast; +// return static_pointer_cast(n)); + return const_pointer(&static_cast(*n)); + } }; } //namespace intrusive diff --git a/include/boost/intrusive/detail/any_node_and_algorithms.hpp b/include/boost/intrusive/detail/any_node_and_algorithms.hpp index e2fbbfa..513bdd9 100644 --- a/include/boost/intrusive/detail/any_node_and_algorithms.hpp +++ b/include/boost/intrusive/detail/any_node_and_algorithms.hpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -87,7 +88,10 @@ struct any_unordered_node_traits static const bool optimize_multikey = true; static node_ptr get_next(const_node_ptr n) - { return node_ptr(&static_cast(*n->node_ptr_1)); } + { + using ::boost::static_pointer_cast; + return static_pointer_cast(n->node_ptr_1); + } static void set_next(node_ptr n, node_ptr next) { n->node_ptr_1 = next; } diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp index 1676b1c..72188b9 100644 --- a/include/boost/intrusive/detail/hashtable_node.hpp +++ b/include/boost/intrusive/detail/hashtable_node.hpp @@ -22,7 +22,7 @@ #include #include //remove-me #include - +#include namespace boost { namespace intrusive { namespace detail { @@ -36,6 +36,7 @@ struct prime_list_holder template const std::size_t prime_list_holder::prime_list[] = { + 3ul, 7ul, 11ul, 17ul, 29ul, 53ul, 97ul, 193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, @@ -117,7 +118,12 @@ class hashtable_iterator typedef typename Container::size_type size_type; static typename Container::node_ptr downcast_bucket(typename bucket_type::node_ptr p) - { return typename Container::node_ptr(&static_cast(*p)); } + { +// This still fails in gcc < 4.4 so forget about it +// using ::boost::static_pointer_cast; +// return static_pointer_cast(p); + return typename Container::node_ptr(&static_cast(*p)); + } public: typedef typename Container::value_type value_type; @@ -164,10 +170,10 @@ class hashtable_iterator { return *this->operator ->(); } pointer operator->() const - { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node()))); } + { return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node()))); } const Container *get_container() const - { return detail::get_pointer(cont_); } + { return detail::boost_intrusive_get_pointer(cont_); } const real_value_traits *get_real_value_traits() const { return &this->get_container()->get_real_value_traits(); } @@ -175,8 +181,8 @@ class hashtable_iterator private: void increment() { - const Container *cont = detail::get_pointer(cont_); - bucket_type* buckets = detail::get_pointer(cont->bucket_pointer()); + const Container *cont = detail::boost_intrusive_get_pointer(cont_); + bucket_type* buckets = detail::boost_intrusive_get_pointer(cont->bucket_pointer()); size_type buckets_len = cont->bucket_count(); ++slist_it_; diff --git a/include/boost/intrusive/detail/list_node.hpp b/include/boost/intrusive/detail/list_node.hpp index 935c522..e5df150 100644 --- a/include/boost/intrusive/detail/list_node.hpp +++ b/include/boost/intrusive/detail/list_node.hpp @@ -64,11 +64,9 @@ class list_iterator : public std::iterator < std::bidirectional_iterator_tag , typename Container::value_type - , typename std::iterator_traits::difference_type - , typename detail::add_const_if_c - ::type * - , typename detail::add_const_if_c - ::type & + , typename Container::difference_type + , typename detail::if_c::type + , typename detail::if_c::type > { protected: @@ -83,10 +81,8 @@ class list_iterator public: typedef typename Container::value_type value_type; - typedef typename detail::add_const_if_c - ::type *pointer; - typedef typename detail::add_const_if_c - ::type &reference; + typedef typename detail::if_c::type pointer; + typedef typename detail::if_c::type reference; list_iterator() : members_ (node_ptr(0), 0) @@ -133,17 +129,17 @@ class list_iterator return result; } - bool operator== (const list_iterator& i) const - { return members_.nodeptr_ == i.pointed_node(); } + friend bool operator== (const list_iterator& l, const list_iterator& r) + { return l.pointed_node() == r.pointed_node(); } - bool operator!= (const list_iterator& i) const - { return !operator== (i); } + friend bool operator!= (const list_iterator& l, const list_iterator& r) + { return !(l == r); } reference operator*() const { return *operator->(); } pointer operator->() const - { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } + { return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } const Container *get_container() const { diff --git a/include/boost/intrusive/detail/parent_from_member.hpp b/include/boost/intrusive/detail/parent_from_member.hpp index 0b30867..c06d932 100644 --- a/include/boost/intrusive/detail/parent_from_member.hpp +++ b/include/boost/intrusive/detail/parent_from_member.hpp @@ -9,8 +9,8 @@ // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// -#ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP -#define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP +#ifndef BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP +#define BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP #include #include @@ -47,15 +47,13 @@ inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_t template inline Parent *parent_from_member(Member *member, const Member Parent::* ptr_to_member) { - return (Parent*)((char*)member - - offset_from_pointer_to_member(ptr_to_member)); + return (Parent*)((char*)member - offset_from_pointer_to_member(ptr_to_member)); } template inline const Parent *parent_from_member(const Member *member, const Member Parent::* ptr_to_member) { - return (const Parent*)((const char*)member - - offset_from_pointer_to_member(ptr_to_member)); + return (const Parent*)((const char*)member - offset_from_pointer_to_member(ptr_to_member)); } } //namespace detail { @@ -68,4 +66,4 @@ inline const Parent *parent_from_member(const Member *member, const Member Paren #include -#endif //#ifndef BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP diff --git a/include/boost/intrusive/detail/slist_node.hpp b/include/boost/intrusive/detail/slist_node.hpp index a7df9e1..6ed8e4b 100644 --- a/include/boost/intrusive/detail/slist_node.hpp +++ b/include/boost/intrusive/detail/slist_node.hpp @@ -56,11 +56,9 @@ class slist_iterator : public std::iterator < std::forward_iterator_tag , typename Container::value_type - , typename std::iterator_traits::difference_type - , typename detail::add_const_if_c - ::type * - , typename detail::add_const_if_c - ::type & + , typename Container::difference_type + , typename detail::if_c::type + , typename detail::if_c::type > { protected: @@ -75,10 +73,8 @@ class slist_iterator public: typedef typename Container::value_type value_type; - typedef typename detail::add_const_if_c - ::type *pointer; - typedef typename detail::add_const_if_c - ::type &reference; + typedef typename detail::if_c::type pointer; + typedef typename detail::if_c::type reference; slist_iterator() : members_ (node_ptr(0), 0) @@ -112,17 +108,17 @@ class slist_iterator return result; } - bool operator== (const slist_iterator& i) const - { return members_.nodeptr_ == i.pointed_node(); } + friend bool operator== (const slist_iterator& l, const slist_iterator& r) + { return l.pointed_node() == r.pointed_node(); } - bool operator!= (const slist_iterator& i) const - { return !operator== (i); } + friend bool operator!= (const slist_iterator& l, const slist_iterator& r) + { return !(l == r); } reference operator*() const { return *operator->(); } pointer operator->() const - { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } + { return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } const Container *get_container() const { diff --git a/include/boost/intrusive/detail/tree_algorithms.hpp b/include/boost/intrusive/detail/tree_algorithms.hpp index 32bbfb5..9ad2b4e 100644 --- a/include/boost/intrusive/detail/tree_algorithms.hpp +++ b/include/boost/intrusive/detail/tree_algorithms.hpp @@ -18,6 +18,7 @@ #include #include #include +//iG pending #include namespace boost { namespace intrusive { @@ -140,7 +141,8 @@ class tree_algorithms static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + return node_ptr(const_cast(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr))); + //iG pending return node_ptr(boost::const_pointer_cast(ptr)); } /// @endcond @@ -1499,7 +1501,7 @@ class tree_algorithms static node_ptr vine_to_subtree(node_ptr old_root, std::size_t count) { - std::size_t leaf_nodes = count + 1 - ((size_t) 1 << floor_log2 (count + 1)); + std::size_t leaf_nodes = count + 1 - ((std::size_t) 1 << floor_log2 (count + 1)); std::size_t vine_nodes = count - leaf_nodes; node_ptr new_root = compress_subtree(old_root, leaf_nodes); diff --git a/include/boost/intrusive/detail/tree_node.hpp b/include/boost/intrusive/detail/tree_node.hpp index 3508e85..f6a678d 100644 --- a/include/boost/intrusive/detail/tree_node.hpp +++ b/include/boost/intrusive/detail/tree_node.hpp @@ -73,11 +73,9 @@ class tree_iterator : public std::iterator < std::bidirectional_iterator_tag , typename Container::value_type - , typename std::iterator_traits::difference_type - , typename detail::add_const_if_c - ::type * - , typename detail::add_const_if_c - ::type & + , typename Container::difference_type + , typename detail::if_c::type + , typename detail::if_c::type > { protected: @@ -93,10 +91,9 @@ class tree_iterator public: typedef typename Container::value_type value_type; - typedef typename detail::add_const_if_c - ::type *pointer; - typedef typename detail::add_const_if_c - ::type &reference; + typedef typename detail::if_c::type pointer; + typedef typename detail::if_c::type reference; + tree_iterator() : members_ (0, 0) @@ -143,17 +140,17 @@ class tree_iterator return result; } - bool operator== (const tree_iterator& i) const - { return members_.nodeptr_ == i.pointed_node(); } + friend bool operator== (const tree_iterator& l, const tree_iterator& r) + { return l.pointed_node() == r.pointed_node(); } - bool operator!= (const tree_iterator& i) const - { return !operator== (i); } + friend bool operator!= (const tree_iterator& l, const tree_iterator& r) + { return !(l == r); } reference operator*() const { return *operator->(); } pointer operator->() const - { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } + { return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } const Container *get_container() const { return static_cast(members_.get_ptr()); } diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index c548911..064ff6e 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -122,10 +122,10 @@ struct smart_ptr_type { return ptr;} }; -//!Overload for smart pointers to avoid ADL problems with get_pointer +//!Overload for smart pointers to avoid ADL problems with boost_intrusive_get_pointer template inline typename smart_ptr_type::pointer -get_pointer(const Ptr &ptr) +boost_intrusive_get_pointer(const Ptr &ptr) { return smart_ptr_type::get(ptr); } //This functor compares a stored value @@ -319,7 +319,7 @@ struct constptr {} const void *get_ptr() const - { return detail::get_pointer(const_void_ptr_); } + { return detail::boost_intrusive_get_pointer(const_void_ptr_); } ConstVoidPtr const_void_ptr_; }; @@ -410,28 +410,63 @@ struct member_hook_traits static const link_mode_type link_mode = Hook::boost_intrusive_tags::link_mode; static node_ptr to_node_ptr(reference value) - { - return reinterpret_cast(&(value.*P)); - } + { return static_cast(&(value.*P)); } static const_node_ptr to_node_ptr(const_reference value) - { - return static_cast(&(value.*P)); - } + { return static_cast(&(value.*P)); } static pointer to_value_ptr(node_ptr n) { return detail::parent_from_member - (static_cast(detail::get_pointer(n)), P); + (static_cast(detail::boost_intrusive_get_pointer(n)), P); } static const_pointer to_value_ptr(const_node_ptr n) { return detail::parent_from_member - (static_cast(detail::get_pointer(n)), P); + (static_cast(detail::boost_intrusive_get_pointer(n)), P); } }; +template +struct function_hook_traits +{ + public: + typedef typename Functor::hook_type hook_type; + typedef typename Functor::hook_ptr hook_ptr; + typedef typename Functor::const_hook_ptr const_hook_ptr; + typedef typename hook_type::boost_intrusive_tags::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename Functor::value_type value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename boost::pointer_to_other::type pointer; + typedef typename boost::pointer_to_other::type const_pointer; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::reference const_reference; + static const link_mode_type link_mode = hook_type::boost_intrusive_tags::link_mode; + + static node_ptr to_node_ptr(reference value) + { return static_cast(&*Functor::to_hook_ptr(value)); } + + static const_node_ptr to_node_ptr(const_reference value) + { return static_cast(&*Functor::to_hook_ptr(value)); } + + static pointer to_value_ptr(node_ptr n) + { return Functor::to_value_ptr(to_hook_ptr(n)); } + + static const_pointer to_value_ptr(const_node_ptr n) + { return Functor::to_value_ptr(to_hook_ptr(n)); } + + private: + static hook_ptr to_hook_ptr(node_ptr n) + { return hook_ptr(&*static_cast(&*n)); } + + static const_hook_ptr to_hook_ptr(const_node_ptr n) + { return const_hook_ptr(&*static_cast(&*n)); } +}; + + //This function uses binary search to discover the //highest set bit of the integer inline std::size_t floor_log2 (std::size_t x) @@ -454,14 +489,19 @@ inline std::size_t floor_log2 (std::size_t x) inline float fast_log2 (float val) { - boost::uint32_t * exp_ptr = - static_cast(static_cast(&val)); - boost::uint32_t x = *exp_ptr; + union caster_t + { + boost::uint32_t x; + float val; + } caster; + + caster.val = val; + boost::uint32_t x = caster.x; const int log_2 = (int)(((x >> 23) & 255) - 128); x &= ~(255 << 23); x += 127 << 23; - *exp_ptr = x; - + caster.x = x; + val = caster.val; val = ((-1.0f/3) * val + 2) * val - 2.0f/3; return (val + log_2); @@ -632,6 +672,64 @@ struct node_to_value { return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); } }; +//This is not standard, but should work with all compilers +union max_align +{ + char char_; + short short_; + int int_; + long long_; + #ifdef BOOST_HAS_LONG_LONG + long long long_long_; + #endif + float float_; + double double_; + long double long_double_; + void * void_ptr_; +}; + +template +class array_initializer +{ + public: + template + array_initializer(const CommonInitializer &init) + { + char *init_buf = (char*)rawbuf; + std::size_t i = 0; + try{ + for(; i != N; ++i){ + new(init_buf)T(init); + init_buf += sizeof(T); + } + } + catch(...){ + while(i--){ + init_buf -= sizeof(T); + ((T*)init_buf)->~T(); + } + throw; + } + } + + operator T* () + { return (T*)(rawbuf); } + + operator const T*() const + { return (const T*)(rawbuf); } + + ~array_initializer() + { + char *init_buf = (char*)rawbuf + N*sizeof(T); + for(std::size_t i = 0; i != N; ++i){ + init_buf -= sizeof(T); + ((T*)init_buf)->~T(); + } + } + + private: + detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1]; +}; } //namespace detail } //namespace intrusive diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp index 51cc6c1..1493eac 100644 --- a/include/boost/intrusive/hashtable.hpp +++ b/include/boost/intrusive/hashtable.hpp @@ -23,6 +23,7 @@ #include #include #include +#include //General intrusive utilities #include #include @@ -157,26 +158,22 @@ struct get_slist_impl_from_supposed_value_traits template struct unordered_bucket_impl { - /// @cond typedef typename get_slist_impl_from_supposed_value_traits ::type slist_impl; typedef detail::bucket_impl implementation_defined; - /// @endcond typedef implementation_defined type; }; template struct unordered_bucket_ptr_impl { - /// @cond typedef typename detail::get_node_traits ::type::node_ptr node_ptr; typedef typename unordered_bucket_impl ::type bucket_type; typedef typename boost::pointer_to_other ::type implementation_defined; - /// @endcond typedef implementation_defined type; }; @@ -329,7 +326,12 @@ struct group_functions typedef circular_slist_algorithms group_algorithms; static node_ptr dcast_bucket_ptr(slist_node_ptr p) - { return node_ptr(&static_cast(*p)); } + { +// This still fails in gcc < 4.4 so forget about it +// using ::boost::static_pointer_cast; +// return static_pointer_cast(p); + return node_ptr(&static_cast(*p)); + } static slist_node_ptr priv_get_bucket_before_begin (slist_node_ptr bucket_beg, slist_node_ptr bucket_end, node_ptr p) @@ -496,7 +498,6 @@ struct unordered_bucket_ptr template struct unordered_default_bucket_traits { - /// @cond typedef typename ValueTraitsOrHookOption:: template pack::value_traits supposed_value_traits; typedef typename detail:: @@ -504,7 +505,6 @@ struct unordered_default_bucket_traits ::type slist_impl; typedef detail::bucket_traits_impl implementation_defined; - /// @endcond typedef implementation_defined type; }; @@ -886,7 +886,7 @@ class hashtable_impl } else{ size_type buckets_len = this->priv_buckets_len(); - const bucket_type *b = detail::get_pointer(this->priv_buckets()); + const bucket_type *b = detail::boost_intrusive_get_pointer(this->priv_buckets()); for (size_type n = 0; n < buckets_len; ++n, ++b){ if(!b->empty()){ return false; @@ -909,7 +909,7 @@ class hashtable_impl else{ size_type len = 0; size_type buckets_len = this->priv_buckets_len(); - const bucket_type *b = detail::get_pointer(this->priv_buckets()); + const bucket_type *b = detail::boost_intrusive_get_pointer(this->priv_buckets()); for (size_type n = 0; n < buckets_len; ++n, ++b){ len += b->size(); } @@ -1229,8 +1229,8 @@ class hashtable_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased element. No destructors are called. - iterator erase(const_iterator i) - { return this->erase_and_dispose(i, detail::null_disposer()); } + void erase(const_iterator i) + { this->erase_and_dispose(i, detail::null_disposer()); } //! Effects: Erases the range pointed to by b end e. //! @@ -1241,8 +1241,8 @@ class hashtable_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, const_iterator e) - { return this->erase_and_dispose(b, e, detail::null_disposer()); } + void erase(const_iterator b, const_iterator e) + { this->erase_and_dispose(b, e, detail::null_disposer()); } //! Effects: Erases all the elements with the given value. //! @@ -1295,18 +1295,15 @@ class hashtable_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator i, Disposer disposer + void erase_and_dispose(const_iterator i, Disposer disposer /// @cond , typename detail::enable_if_c::value >::type * = 0 /// @endcond ) { - iterator ret(i.unconst()); - ++ret; priv_erase(i, disposer, optimize_multikey_t()); this->priv_size_traits().decrement(); priv_erasure_update_cache(); - return ret; } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -1322,7 +1319,7 @@ class hashtable_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) { if(b != e){ //Get the bucket number and local iterator for both iterators @@ -1347,7 +1344,6 @@ class hashtable_impl priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer); priv_erasure_update_cache(first_bucket_num, last_bucket_num); } - return e.unconst(); } //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -2139,8 +2135,8 @@ class hashtable_impl } //! Effects: Returns the nearest new bucket count optimized for - //! the container that is bigger than n. This suggestion can be used - //! to create bucket arrays with a size that will usually improve + //! the container that is bigger or equal than n. This suggestion can be + //! used to create bucket arrays with a size that will usually improve //! container's performance. If such value does not exist, the //! higher possible value is returned. //! @@ -2153,15 +2149,15 @@ class hashtable_impl const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size; size_type const* bound = std::lower_bound(primes, primes_end, n); if(bound == primes_end) - bound--; + --bound; return size_type(*bound); } //! Effects: Returns the nearest new bucket count optimized for - //! the container that is smaller than n. This suggestion can be used - //! to create bucket arrays with a size that will usually improve + //! the container that is smaller or equal than n. This suggestion can be + //! used to create bucket arrays with a size that will usually improve //! container's performance. If such value does not exist, the - //! lower possible value is returned. + //! lowest possible value is returned. //! //! Complexity: Amortized constant time. //! @@ -2171,8 +2167,8 @@ class hashtable_impl const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0]; const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size; size_type const* bound = std::upper_bound(primes, primes_end, n); - if(bound != primes_end) - bound--; + if(bound != primes) + --bound; return size_type(*bound); } @@ -2240,7 +2236,7 @@ class hashtable_impl { return this->priv_real_bucket_traits().bucket_count(); } static node_ptr uncast(const_node_ptr ptr) - { return node_ptr(const_cast(detail::get_pointer(ptr))); } + { return node_ptr(const_cast(detail::boost_intrusive_get_pointer(ptr))); } node &priv_value_to_node(value_type &v) { return *this->get_real_value_traits().to_node_ptr(v); } @@ -2326,7 +2322,12 @@ class hashtable_impl } static node_ptr dcast_bucket_ptr(typename slist_impl::node_ptr p) - { return node_ptr(&static_cast(*p)); } + { +// This still fails in gcc < 4.4 so forget about it +// using ::boost::static_pointer_cast; +// return static_pointer_cast(p); + return node_ptr(&static_cast(*p)); + } std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const { return node_traits::get_hash(this->get_real_value_traits().to_node_ptr(v)); } @@ -2893,7 +2894,6 @@ struct make_hashtable_opt //Real value traits must be calculated from options typedef typename detail::get_value_traits ::type value_traits; - /// @cond static const bool external_value_traits = detail::external_value_traits_is_true::value; typedef typename detail::eval_if_c @@ -2902,7 +2902,6 @@ struct make_hashtable_opt , detail::identity >::type real_value_traits; typedef typename packed_options::bucket_traits specified_bucket_traits; - /// @endcond //Real bucket traits must be calculated from options and calculated value_traits typedef typename detail::get_slist_impl diff --git a/include/boost/intrusive/intrusive_fwd.hpp b/include/boost/intrusive/intrusive_fwd.hpp index 7c9b2a1..dc18566 100644 --- a/include/boost/intrusive/intrusive_fwd.hpp +++ b/include/boost/intrusive/intrusive_fwd.hpp @@ -50,7 +50,7 @@ class rbtree_algorithms; //////////////////////////// //slist -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -64,7 +64,7 @@ template #endif class slist; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -75,7 +75,7 @@ template #endif class slist_base_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -87,7 +87,7 @@ template class slist_member_hook; //list -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -99,7 +99,7 @@ template #endif class list; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -110,7 +110,7 @@ template #endif class list_base_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -121,8 +121,19 @@ template #endif class list_member_hook; +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = none + , class O2 = none + , class O3 = none + > +#else +template +#endif +class list_hook; + //rbtree/set/multiset -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -135,7 +146,7 @@ template #endif class rbtree; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -148,7 +159,7 @@ template #endif class set; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -161,7 +172,7 @@ template #endif class multiset; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -173,7 +184,7 @@ template #endif class set_base_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -186,7 +197,7 @@ template class set_member_hook; //splaytree/splay_set/splay_multiset -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -199,7 +210,7 @@ template #endif class splaytree; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -212,7 +223,7 @@ template #endif class splay_set; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -225,7 +236,7 @@ template #endif class splay_multiset; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -236,7 +247,7 @@ template #endif class splay_set_base_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -248,7 +259,7 @@ template class splay_set_member_hook; //avltree/avl_set/avl_multiset -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -261,7 +272,7 @@ template #endif class avltree; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -274,7 +285,7 @@ template #endif class avl_set; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -287,7 +298,7 @@ template #endif class avl_multiset; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -299,7 +310,7 @@ template #endif class avl_set_base_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -313,7 +324,7 @@ class avl_set_member_hook; //treap/treap_set/treap_multiset -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -326,7 +337,7 @@ template #endif class treap; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -339,7 +350,7 @@ template #endif class treap_set; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -357,7 +368,7 @@ template struct priority_compare; //sgtree/sg_set/sg_multiset -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -370,7 +381,7 @@ template #endif class sgtree; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -383,7 +394,7 @@ template #endif class sg_set; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -396,7 +407,7 @@ template #endif class sg_multiset; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -407,7 +418,7 @@ template #endif class bs_set_base_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -420,7 +431,7 @@ class bs_set_member_hook; //hashtable/unordered_set/unordered_multiset -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -439,7 +450,7 @@ template #endif class hashtable; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -458,7 +469,7 @@ template #endif class unordered_set; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class T , class O1 = none @@ -477,7 +488,7 @@ template #endif class unordered_multiset; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -489,7 +500,7 @@ template #endif class unordered_set_base_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -501,7 +512,7 @@ template #endif class unordered_set_member_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none @@ -512,7 +523,7 @@ template #endif class any_base_hook; -#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template < class O1 = none , class O2 = none diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index 965baa7..ee3e5ba 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -30,6 +30,7 @@ #include #include #include +//iG pending #include namespace boost { namespace intrusive { @@ -129,8 +130,8 @@ class list_impl //Const cast emulation for smart pointers static node_ptr uncast(const_node_ptr ptr) { - //return node_ptr(detail::get_pointer(ptr))); - return const_cast(detail::get_pointer(ptr)); + return const_cast(detail::boost_intrusive_get_pointer(ptr)); + //iG pending return node_ptr(boost::const_pointer_cast(ptr)); } node_ptr get_root_node() @@ -172,6 +173,22 @@ class list_impl real_value_traits &get_real_value_traits(detail::bool_) { return data_.get_value_traits(*this); } + const value_traits &get_value_traits() const + { return data_; } + + value_traits &get_value_traits() + { return data_; } + + protected: + node &prot_root_node() + { return data_.root_plus_size_.root_; } + + node const &prot_root_node() const + { return data_.root_plus_size_.root_; } + + void prot_set_size(size_type s) + { data_.root_plus_size_.set_size(s); } + /// @endcond public: @@ -971,8 +988,8 @@ class list_impl { if(node_traits::get_next(this->get_root_node()) != node_traits::get_previous(this->get_root_node())){ - list_impl carry; - list_impl counter[64]; + list_impl carry(this->get_value_traits()); + detail::array_initializer counter(this->get_value_traits()); int fill = 0; while(!this->empty()){ carry.splice(carry.cbegin(), *this, this->cbegin()); @@ -1268,7 +1285,7 @@ class list_impl static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { root_plus_size *r = detail::parent_from_member - ( detail::get_pointer(end_iterator.pointed_node()), &root_plus_size::root_); + ( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &root_plus_size::root_); data_t *d = detail::parent_from_member ( r, &data_t::root_plus_size_); list_impl *s = detail::parent_from_member(d, &list_impl::data_); diff --git a/include/boost/intrusive/options.hpp b/include/boost/intrusive/options.hpp index d692b1e..9731651 100644 --- a/include/boost/intrusive/options.hpp +++ b/include/boost/intrusive/options.hpp @@ -343,6 +343,24 @@ struct member_hook }; +//!This option setter specifies the function object that will +//!be used to convert between values to be inserted in a container +//!and the hook to be used for that purpose. +template< typename Functor> +struct function_hook +{ +/// @cond + typedef detail::function_hook_traits + function_value_traits; + template + struct pack : Base + { + typedef function_value_traits value_traits; + }; +/// @endcond +}; + + //!This option setter specifies that the container //!must use the specified base hook template diff --git a/include/boost/intrusive/parent_from_member.hpp b/include/boost/intrusive/parent_from_member.hpp new file mode 100644 index 0000000..882c073 --- /dev/null +++ b/include/boost/intrusive/parent_from_member.hpp @@ -0,0 +1,42 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2010-2010 +// +// 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/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_GET_PARENT_FROM_MEMBER_HPP +#define BOOST_INTRUSIVE_GET_PARENT_FROM_MEMBER_HPP + +#include +#include + +namespace boost { +namespace intrusive { + +//! Given a pointer to a member and its corresponding pointer to data member, +//! this function returns the pointer of the parent containing that member. +//! Note: this function does not work with pointer to members that rely on +//! virtual inheritance. +template +inline Parent *get_parent_from_member(Member *member, const Member Parent::* ptr_to_member) +{ return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); } + +//! Given a const pointer to a member and its corresponding const pointer to data member, +//! this function returns the const pointer of the parent containing that member. +//! Note: this function does not work with pointer to members that rely on +//! virtual inheritance. +template +inline const Parent *get_parent_from_member(const Member *member, const Member Parent::* ptr_to_member) +{ return ::boost::intrusive::detail::parent_from_member(member, ptr_to_member); } + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_GET_PARENT_FROM_MEMBER_HPP diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index 8d9cacf..c8e8ab5 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -33,6 +33,7 @@ #include #include #include +//iG pending #include namespace boost { namespace intrusive { @@ -110,10 +111,8 @@ class rbtree_impl typedef std::reverse_iterator const_reverse_iterator; typedef typename real_value_traits::node_traits node_traits; typedef typename node_traits::node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; typedef rbtree_algorithms node_algorithms; static const bool constant_time_size = Config::constant_time_size; @@ -152,7 +151,7 @@ class rbtree_impl {} node_plus_pred_t node_plus_pred_; } data_; - + const value_compare &priv_comp() const { return data_.node_plus_pred_.get(); } @@ -167,7 +166,8 @@ class rbtree_impl static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(detail::get_pointer(ptr))); + return node_ptr(const_cast(detail::boost_intrusive_get_pointer(ptr))); +//iG pending return node_ptr(boost::const_pointer_cast(ptr)); } size_traits &priv_size_traits() @@ -188,6 +188,19 @@ class rbtree_impl real_value_traits &get_real_value_traits(detail::bool_) { return data_.get_value_traits(*this); } + protected: + value_compare &prot_comp() + { return priv_comp(); } + + const node &prot_header_node() const + { return priv_header(); } + + node &prot_header_node() + { return priv_header(); } + + void prot_set_size(size_type s) + { this->priv_size_traits().set_size(s); } + /// @endcond public: @@ -1390,7 +1403,7 @@ class rbtree_impl static rbtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { header_plus_size *r = detail::parent_from_member - ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); + ( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); node_plus_pred_t *n = detail::parent_from_member (r, &node_plus_pred_t::header_plus_size_); data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_); diff --git a/include/boost/intrusive/rbtree_algorithms.hpp b/include/boost/intrusive/rbtree_algorithms.hpp index ca6f7eb..5458e4f 100644 --- a/include/boost/intrusive/rbtree_algorithms.hpp +++ b/include/boost/intrusive/rbtree_algorithms.hpp @@ -57,7 +57,6 @@ #include #include - namespace boost { namespace intrusive { @@ -157,7 +156,7 @@ class rbtree_algorithms static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + return node_ptr(const_cast(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr))); } /// @endcond diff --git a/include/boost/intrusive/set.hpp b/include/boost/intrusive/set.hpp index 54c5a65..c85ab08 100644 --- a/include/boost/intrusive/set.hpp +++ b/include/boost/intrusive/set.hpp @@ -75,9 +75,19 @@ class set_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; + static const bool constant_time_size = Config::constant_time_size; + //static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + /// @cond private: tree_type tree_; + + protected: + node &prot_header_node(){ return tree_.prot_header_node(); } + node const &prot_header_node() const{ return tree_.prot_header_node(); } + void prot_set_size(size_type s){ tree_.prot_set_size(s); } + value_compare &prot_comp(){ return tree_.prot_comp(); } + /// @endcond public: @@ -1265,9 +1275,18 @@ class multiset_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; + static const bool constant_time_size = Config::constant_time_size; + //static const bool stateful_value_traits = detail::is_stateful_value_traits::value; + /// @cond private: tree_type tree_; + + protected: + node &prot_header_node(){ return tree_.prot_header_node(); } + node const &prot_header_node() const{ return tree_.prot_header_node(); } + void prot_set_size(size_type s){ tree_.prot_set_size(s); } + value_compare &prot_comp(){ return tree_.prot_comp(); } /// @endcond public: @@ -1450,7 +1469,7 @@ class multiset_impl //! //! Throws: Nothing. //! - //! Complexity: Constant. + //! Complexity: Logarithmic. static multiset_impl &container_from_iterator(iterator it) { return *detail::parent_from_member @@ -1464,7 +1483,7 @@ class multiset_impl //! //! Throws: Nothing. //! - //! Complexity: Constant. + //! Complexity: Logarithmic. static const multiset_impl &container_from_iterator(const_iterator it) { return *detail::parent_from_member diff --git a/include/boost/intrusive/sgtree_algorithms.hpp b/include/boost/intrusive/sgtree_algorithms.hpp index bb6ef06..99e9d39 100644 --- a/include/boost/intrusive/sgtree_algorithms.hpp +++ b/include/boost/intrusive/sgtree_algorithms.hpp @@ -70,7 +70,7 @@ class sgtree_algorithms static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + return node_ptr(const_cast(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr))); } /// @endcond diff --git a/include/boost/intrusive/splay_set.hpp b/include/boost/intrusive/splay_set.hpp index 9727d14..f899e78 100644 --- a/include/boost/intrusive/splay_set.hpp +++ b/include/boost/intrusive/splay_set.hpp @@ -74,6 +74,8 @@ class splay_set_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; + static const bool constant_time_size = Config::constant_time_size; + /// @cond private: tree_type tree_; @@ -1286,6 +1288,8 @@ class splay_multiset_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; + static const bool constant_time_size = Config::constant_time_size; + /// @cond private: tree_type tree_; diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index 4020c85..1cb2a2a 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -166,7 +166,7 @@ class splaytree_impl static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(detail::get_pointer(ptr))); + return node_ptr(const_cast(detail::boost_intrusive_get_pointer(ptr))); } size_traits &priv_size_traits() @@ -1405,7 +1405,7 @@ class splaytree_impl static splaytree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { header_plus_size *r = detail::parent_from_member - ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); + ( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); node_plus_pred_t *n = detail::parent_from_member (r, &node_plus_pred_t::header_plus_size_); data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_); diff --git a/include/boost/intrusive/splaytree_algorithms.hpp b/include/boost/intrusive/splaytree_algorithms.hpp index eb25e9f..777b3b9 100644 --- a/include/boost/intrusive/splaytree_algorithms.hpp +++ b/include/boost/intrusive/splaytree_algorithms.hpp @@ -147,7 +147,7 @@ class splaytree_algorithms private: static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + return node_ptr(const_cast(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr))); } /// @endcond diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index b7c9ed2..86bdd01 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -116,7 +116,7 @@ class treap_impl ::type node_ptr; typedef typename boost::pointer_to_other ::type const_node_ptr; - typedef treap_algorithms node_algorithms; + typedef treap_algorithms node_algorithms; static const bool constant_time_size = Config::constant_time_size; static const bool stateful_value_traits = detail::is_stateful_value_traits::value; @@ -184,7 +184,7 @@ class treap_impl static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(detail::get_pointer(ptr))); + return node_ptr(const_cast(detail::boost_intrusive_get_pointer(ptr))); } size_traits &priv_size_traits() @@ -1482,7 +1482,7 @@ class treap_impl static treap_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { header_plus_size *r = detail::parent_from_member - ( detail::get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); + ( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); typename node_plus_pred_t::header_plus_priority_size *n = detail::parent_from_member < typename node_plus_pred_t::header_plus_priority_size diff --git a/include/boost/intrusive/treap_algorithms.hpp b/include/boost/intrusive/treap_algorithms.hpp index 6c05efa..a120815 100644 --- a/include/boost/intrusive/treap_algorithms.hpp +++ b/include/boost/intrusive/treap_algorithms.hpp @@ -145,7 +145,7 @@ class treap_algorithms static node_ptr uncast(const_node_ptr ptr) { - return node_ptr(const_cast(::boost::intrusive::detail::get_pointer(ptr))); + return node_ptr(const_cast(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr))); } /// @endcond diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index 12611ee..ef38a1e 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -75,6 +75,8 @@ class treap_set_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; + static const bool constant_time_size = Config::constant_time_size; + /// @cond private: tree_type tree_; @@ -1382,6 +1384,8 @@ class treap_multiset_impl typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef typename implementation_defined::node_algorithms node_algorithms; + static const bool constant_time_size = Config::constant_time_size; + /// @cond private: tree_type tree_; diff --git a/include/boost/intrusive/unordered_set.hpp b/include/boost/intrusive/unordered_set.hpp index 47d1aab..2b40f61 100644 --- a/include/boost/intrusive/unordered_set.hpp +++ b/include/boost/intrusive/unordered_set.hpp @@ -248,7 +248,7 @@ class unordered_set_impl //! Effects: Returns the number of elements stored in the unordered_set. //! //! Complexity: Linear to elements contained in *this if - //! constant-time size option is enabled. Constant-time otherwise. + //! constant-time size option is disabled. Constant-time otherwise. //! //! Throws: Nothing. size_type size() const @@ -395,8 +395,8 @@ class unordered_set_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased element. No destructors are called. - iterator erase(const_iterator i) - { return table_.erase(i); } + void erase(const_iterator i) + { table_.erase(i); } //! Effects: Erases the range pointed to by b end e. //! @@ -407,8 +407,8 @@ class unordered_set_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, const_iterator e) - { return table_.erase(b, e); } + void erase(const_iterator b, const_iterator e) + { table_.erase(b, e); } //! Effects: Erases all the elements with the given value. //! @@ -460,12 +460,12 @@ class unordered_set_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator i, Disposer disposer + void erase_and_dispose(const_iterator i, Disposer disposer /// @cond , typename detail::enable_if_c::value >::type * = 0 /// @endcond ) - { return table_.erase_and_dispose(i, disposer); } + { table_.erase_and_dispose(i, disposer); } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! @@ -480,8 +480,8 @@ class unordered_set_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) - { return table_.erase_and_dispose(b, e, disposer); } + void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + { table_.erase_and_dispose(b, e, disposer); } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! @@ -1305,7 +1305,7 @@ class unordered_multiset_impl //! Effects: Returns the number of elements stored in the unordered_multiset. //! //! Complexity: Linear to elements contained in *this if - //! constant-time size option is enabled. Constant-time otherwise. + //! constant-time size option is disabled. Constant-time otherwise. //! //! Throws: Nothing. size_type size() const @@ -1387,8 +1387,8 @@ class unordered_multiset_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased element. No destructors are called. - iterator erase(const_iterator i) - { return table_.erase(i); } + void erase(const_iterator i) + { table_.erase(i); } //! Effects: Erases the range pointed to by b end e. //! @@ -1399,8 +1399,8 @@ class unordered_multiset_impl //! //! Note: Invalidates the iterators (but not the references) //! to the erased elements. No destructors are called. - iterator erase(const_iterator b, const_iterator e) - { return table_.erase(b, e); } + void erase(const_iterator b, const_iterator e) + { table_.erase(b, e); } //! Effects: Erases all the elements with the given value. //! @@ -1453,17 +1453,17 @@ class unordered_multiset_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator i, Disposer disposer + void erase_and_dispose(const_iterator i, Disposer disposer /// @cond , typename detail::enable_if_c::value >::type * = 0 /// @endcond ) - { return table_.erase_and_dispose(i, disposer); } + { table_.erase_and_dispose(i, disposer); } #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template - iterator erase_and_dispose(const_iterator i, Disposer disposer) - { return this->erase_and_dispose(const_iterator(i), disposer); } + void erase_and_dispose(const_iterator i, Disposer disposer) + { this->erase_and_dispose(const_iterator(i), disposer); } #endif //! Requires: Disposer::operator()(pointer) shouldn't throw. @@ -1479,8 +1479,8 @@ class unordered_multiset_impl //! Note: Invalidates the iterators //! to the erased elements. template - iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) - { return table_.erase_and_dispose(b, e, disposer); } + void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) + { table_.erase_and_dispose(b, e, disposer); } //! Requires: Disposer::operator()(pointer) shouldn't throw. //! diff --git a/include/boost/intrusive/unordered_set_hook.hpp b/include/boost/intrusive/unordered_set_hook.hpp index 286b318..61f4a72 100644 --- a/include/boost/intrusive/unordered_set_hook.hpp +++ b/include/boost/intrusive/unordered_set_hook.hpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -76,7 +77,12 @@ struct unordered_node_traits static const bool optimize_multikey = OptimizeMultiKey; static node_ptr get_next(const_node_ptr n) - { return node_ptr(&static_cast(*n->next_)); } + { +// This still fails in gcc < 4.4 so forget about it +// using ::boost::static_pointer_cast; +// return static_pointer_cast(n->next_); + return node_ptr(&static_cast(*n->next_)); + } static void set_next(node_ptr n, node_ptr next) { n->next_ = next; }