diff --git a/include/boost/intrusive/circular_list_algorithms.hpp b/include/boost/intrusive/circular_list_algorithms.hpp index 08f86b2..5dfb2d6 100644 --- a/include/boost/intrusive/circular_list_algorithms.hpp +++ b/include/boost/intrusive/circular_list_algorithms.hpp @@ -15,10 +15,7 @@ #define BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP #include -#include -#include #include -#include #include namespace boost { @@ -175,8 +172,10 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. +/* static void swap_nodes(node_ptr this_node, node_ptr other_node) { + if (other_node == this_node) return; bool empty1 = unique(this_node); @@ -209,7 +208,8 @@ class circular_list_algorithms NodeTraits::set_previous(next_this, other_node); } } -/* +*/ + //Watanabe version private: static void swap_prev(node_ptr this_node, node_ptr other_node) @@ -238,7 +238,7 @@ class circular_list_algorithms swap_next(this_node, other_node); swap_prev(this_node, other_node); } -*/ + //! Requires: b and e must be nodes of the same circular list or an empty range. //! and p must be a node of a different circular list or may not be an iterator in // [b, e). diff --git a/include/boost/intrusive/circular_slist_algorithms.hpp b/include/boost/intrusive/circular_slist_algorithms.hpp index 4a57a45..cbb1d20 100644 --- a/include/boost/intrusive/circular_slist_algorithms.hpp +++ b/include/boost/intrusive/circular_slist_algorithms.hpp @@ -15,10 +15,7 @@ #define BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP #include -#include -#include #include -#include #include namespace boost { @@ -202,7 +199,8 @@ class circular_slist_algorithms //! Throws: Nothing. static void link_after(node_ptr prev_node, node_ptr this_node) { - NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node)); + node_ptr this_nxt = NodeTraits::get_next(prev_node); + NodeTraits::set_next(this_node, this_nxt); NodeTraits::set_next(prev_node, this_node); } diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp index 1f7e1a3..e2f8653 100644 --- a/include/boost/intrusive/detail/hashtable_node.hpp +++ b/include/boost/intrusive/detail/hashtable_node.hpp @@ -18,9 +18,13 @@ #include #include #include +#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE #include +#endif +#ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE #include #include +#endif #include namespace boost { @@ -102,6 +106,8 @@ struct bucket_info_impl size_type buckets_len_; }; +#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE + template class hashtable_iterator : public boost::iterator_facade @@ -138,6 +144,8 @@ class hashtable_iterator : local_it_ (ptr), bucket_info_ (bucket_info) {} + + #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE template hashtable_iterator(hashtable_iterator const& other ,typename boost::enable_if< @@ -147,6 +155,15 @@ class hashtable_iterator ) : local_it_(other.local_it_), bucket_info_(other.bucket_info_) {} + #else + template + hashtable_iterator(hashtable_iterator const& other, + typename enable_if< + is_convertible + >::type* = 0) + : local_it_(other.local_it_), bucket_info_(other.bucket_info_) + {} + #endif const local_iterator &local() const { return local_it_; } @@ -195,6 +212,123 @@ class hashtable_iterator const_bucket_info_ptr bucket_info_; }; +#else + +template +class hashtable_iterator + : public std::iterator +{ + typedef typename SlistImpl::iterator local_iterator; + typedef typename SlistImpl::const_iterator const_local_iterator; + typedef typename SlistImpl::value_traits::node_ptr node_ptr; + typedef typename SlistImpl::value_traits::const_node_ptr const_node_ptr; + + typedef bucket_type_impl bucket_type; + typedef typename boost::pointer_to_other + < typename SlistImpl::pointer, bucket_type>::type bucket_ptr; + typedef typename boost::pointer_to_other + < typename SlistImpl::pointer, const bucket_type>::type const_bucket_ptr; + typedef detail::bucket_info_impl bucket_info_t; + typedef typename boost::pointer_to_other + ::type bucket_info_ptr; + typedef typename boost::pointer_to_other + ::type const_bucket_info_ptr; + typedef typename SlistImpl::size_type size_type; + struct enabler {}; + + public: + typedef T & reference; + typedef T * pointer; + + hashtable_iterator () + {} + + explicit hashtable_iterator(local_iterator ptr, const_bucket_info_ptr bucket_info) + : local_it_ (ptr), bucket_info_ (bucket_info) + {} + + + #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE + template + hashtable_iterator(hashtable_iterator const& other + ,typename boost::enable_if< + boost::is_convertible + , enabler + >::type = enabler() + ) + : local_it_(other.local_it_), bucket_info_(other.bucket_info_) + {} + #else + template + hashtable_iterator(hashtable_iterator const& other, + typename enable_if< + is_convertible + >::type* = 0) + : local_it_(other.local_it_), bucket_info_(other.bucket_info_) + {} + #endif + + const local_iterator &local() const + { return local_it_; } + + const_node_ptr pointed_node() const + { return local_it_.pointed_node(); } + + const const_bucket_info_ptr &bucket_info() const + { return bucket_info_; } + + public: + hashtable_iterator& operator++() + { increment(); return *this; } + + hashtable_iterator operator++(int) + { + hashtable_iterator result (*this); + increment(); + return result; + } + + friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2) + { return i.pointed_node() == i2.pointed_node(); } + + friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2) + { return !(i == i2); } + + T& operator*() const + { return *local_it_; } + + pointer operator->() const + { return &(*local_it_); } + + private: + void increment() + { + size_type buckets_len = bucket_info_->buckets_len_; + const_bucket_ptr buckets = bucket_info_->buckets_; + const_local_iterator first = bucket_type::bucket_to_slist(buckets[0]).cend(); + const_local_iterator last = bucket_type::bucket_to_slist(buckets[buckets_len]).cend(); + + ++local_it_; + if(first.pointed_node() <= local_it_.pointed_node() && + local_it_.pointed_node() <= last.pointed_node()){ + size_type n_bucket = (size_type) + bucket_type::get_bucket_num(local_it_, buckets[0], buckets[buckets_len]); + do{ + if (++n_bucket == buckets_len){ + local_it_ = bucket_info_->buckets_->end(); + break; + } + local_it_ = bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).begin(); + } + while (local_it_ == bucket_type::bucket_to_slist(bucket_info_->buckets_[n_bucket]).end()); + } + } + + local_iterator local_it_; + const_bucket_info_ptr bucket_info_; +}; +#endif + } //namespace detail { } //namespace intrusive { } //namespace boost { diff --git a/include/boost/intrusive/detail/list_node.hpp b/include/boost/intrusive/detail/list_node.hpp index 84f79b5..e3a67c7 100644 --- a/include/boost/intrusive/detail/list_node.hpp +++ b/include/boost/intrusive/detail/list_node.hpp @@ -26,7 +26,6 @@ #include #include #endif -#include namespace boost { namespace intrusive { @@ -94,6 +93,7 @@ class list_iterator : node_ (node) {} + #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE template list_iterator(list_iterator const& other ,typename boost::enable_if< @@ -103,6 +103,15 @@ class list_iterator ) : node_(other.pointed_node()) {} + #else + template + list_iterator(list_iterator const& other, + typename enable_if< + is_convertible + >::type* = 0) + : node_(other.pointed_node()) + {} + #endif const node_ptr &pointed_node() const { return node_; } diff --git a/include/boost/intrusive/detail/parent_from_member.hpp b/include/boost/intrusive/detail/parent_from_member.hpp index 2a7389f..93b46e3 100644 --- a/include/boost/intrusive/detail/parent_from_member.hpp +++ b/include/boost/intrusive/detail/parent_from_member.hpp @@ -21,11 +21,14 @@ namespace detail { template std::size_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member) { - //This works with gcc and msvc //The implementation of a pointer to member is compiler dependent. - #if defined(BOOST_MSVC) || defined(__GNUC__) || defined(BOOST_INTEL) + #if defined(BOOST_MSVC) || defined(__GNUC__) || \ + defined(BOOST_INTEL) || defined(__HP_aCC) || \ + defined(__EDG_VERSION__) + //This works with gcc, msvc, edg, ac++ return *(const std::size_t*)(const void*)&ptr_to_member; - #else //CW 9.4 + #else + //This is the traditional C-front approach: CW 9.4, dmc return *(const std::size_t*)(const void*)&ptr_to_member - 1; #endif } diff --git a/include/boost/intrusive/detail/rbtree_node.hpp b/include/boost/intrusive/detail/rbtree_node.hpp index 91baf5c..dbcfe2b 100644 --- a/include/boost/intrusive/detail/rbtree_node.hpp +++ b/include/boost/intrusive/detail/rbtree_node.hpp @@ -16,12 +16,8 @@ #include #include -#include #include #include -#include -#include -#include #ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE #include #endif @@ -219,6 +215,7 @@ class rbtree_iterator : node_ (node) {} + #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE template rbtree_iterator(rbtree_iterator const& other ,typename boost::enable_if< @@ -228,6 +225,15 @@ class rbtree_iterator ) : node_(other.pointed_node()) {} + #else + template + rbtree_iterator(rbtree_iterator const& other, + typename enable_if< + is_convertible + >::type* = 0) + : node_(other.pointed_node()) + {} + #endif const node_ptr &pointed_node() const { return node_; } diff --git a/include/boost/intrusive/detail/slist_node.hpp b/include/boost/intrusive/detail/slist_node.hpp index f9d3b25..b82e895 100644 --- a/include/boost/intrusive/detail/slist_node.hpp +++ b/include/boost/intrusive/detail/slist_node.hpp @@ -26,7 +26,6 @@ #include #include #endif -#include namespace boost { namespace intrusive { @@ -154,21 +153,26 @@ class slist_iterator explicit slist_iterator(node_ptr node) : node_ (node) {} -/* + + #ifdef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE template slist_iterator(slist_iterator const& other - ,typename boost::enable_if< + ,typename boost::enable_if< boost::is_convertible , enabler >::type = enabler() - ) + ) : node_(other.pointed_node()) {} -*/ + #else template - slist_iterator(slist_iterator const& other) + slist_iterator(slist_iterator const& other, + typename enable_if< + is_convertible + >::type* = 0) : node_(other.pointed_node()) {} + #endif const node_ptr &pointed_node() const { return node_; } diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp index 2835b6b..6ab8e20 100644 --- a/include/boost/intrusive/hashtable.hpp +++ b/include/boost/intrusive/hashtable.hpp @@ -15,7 +15,6 @@ #include //std C++ #include -#include #include #include //boost @@ -33,7 +32,6 @@ #include #include #include -#include namespace boost { namespace intrusive { diff --git a/include/boost/intrusive/rbtree_algorithms.hpp b/include/boost/intrusive/rbtree_algorithms.hpp index 3b40e2d..cd27731 100644 --- a/include/boost/intrusive/rbtree_algorithms.hpp +++ b/include/boost/intrusive/rbtree_algorithms.hpp @@ -40,11 +40,8 @@ #define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP #include -#include #include #include -#include -#include #include #include #include @@ -66,7 +63,7 @@ namespace intrusive { //! //! (2) when a node being deleted has two children its successor node is //! relinked into its place, rather than copied, so that the only -//! iterators invalidated are those referring to the deleted node. +//! pointers invalidated are those referring to the deleted node. //! //! rbtree_algorithms is configured with a NodeTraits class, which capsulates the //! information about the node to be manipulated. NodeTraits must support the