diff --git a/include/boost/intrusive/any_hook.hpp b/include/boost/intrusive/any_hook.hpp index b1b0194..cccc820 100644 --- a/include/boost/intrusive/any_hook.hpp +++ b/include/boost/intrusive/any_hook.hpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include namespace boost { namespace intrusive { @@ -244,15 +244,15 @@ namespace detail{ template struct any_to_get_base_pointer_type { - typedef typename pointer_to_other - ::type type; + typedef typename pointer_traits::template + rebind_pointer::type type; }; template struct any_to_get_member_pointer_type { - typedef typename pointer_to_other - ::type type; + typedef typename pointer_traits + ::template rebind_pointer::type type; }; //!This option setter specifies that the container diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index 5857471..20903dd 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -27,9 +27,11 @@ #include #include #include -#include +#include +#include #include #include +#include #include #include #include @@ -96,24 +98,30 @@ class avltree_impl /// @endcond typedef typename real_value_traits::pointer pointer; typedef typename real_value_traits::const_pointer const_pointer; - typedef typename std::iterator_traits::value_type value_type; + typedef typename boost::intrusive:: + pointer_traits::element_type value_type; typedef value_type key_type; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::reference const_reference; - typedef typename std::iterator_traits::difference_type difference_type; + typedef typename boost::intrusive:: + pointer_traits::reference reference; + typedef typename boost::intrusive:: + pointer_traits::reference const_reference; + typedef typename boost::intrusive:: + pointer_traits::difference_type difference_type; typedef typename Config::size_type size_type; typedef typename Config::compare value_compare; typedef value_compare key_compare; - typedef tree_iterator iterator; - typedef tree_iterator const_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef tree_iterator iterator; + typedef tree_iterator const_iterator; + typedef boost::intrusive::detail::reverse_iterator reverse_iterator; + typedef boost::intrusive::detail::reverse_iteratorconst_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 pointer_traits + ::template rebind_pointer + ::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer + ::type const_node_ptr; typedef avltree_algorithms node_algorithms; static const bool constant_time_size = Config::constant_time_size; @@ -165,16 +173,14 @@ class avltree_impl value_traits &priv_value_traits() { return data_; } - const node &priv_header() const - { return data_.node_plus_pred_.header_plus_size_.header_; } + node_ptr priv_header_ptr() + { return pointer_traits::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); } - node &priv_header() - { return data_.node_plus_pred_.header_plus_size_.header_; } + const_node_ptr priv_header_ptr() const + { return pointer_traits::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); } - static node_ptr uncast(const_node_ptr ptr) - { - return node_ptr(const_cast(detail::boost_intrusive_get_pointer(ptr))); - } + static node_ptr uncast(const const_node_ptr & ptr) + { return pointer_traits::const_cast_from(ptr); } size_traits &priv_size_traits() { return data_.node_plus_pred_.header_plus_size_; } @@ -217,7 +223,7 @@ class avltree_impl , const value_traits &v_traits = value_traits()) : data_(cmp, v_traits) { - node_algorithms::init_header(&priv_header()); + node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(size_type(0)); } @@ -239,7 +245,7 @@ class avltree_impl , const value_traits &v_traits = value_traits()) : data_(cmp, v_traits) { - node_algorithms::init_header(&priv_header()); + node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(size_type(0)); if(unique) this->insert_unique(b, e); @@ -252,7 +258,7 @@ class avltree_impl avltree_impl(BOOST_RV_REF(avltree_impl) x) : data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits())) { - node_algorithms::init_header(&priv_header()); + node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(size_type(0)); this->swap(x); } @@ -278,7 +284,7 @@ class avltree_impl //! //! Throws: Nothing. iterator begin() - { return iterator (node_traits::get_left(node_ptr(&priv_header())), this); } + { return iterator (node_traits::get_left(this->priv_header_ptr()), this); } //! Effects: Returns a const_iterator pointing to the beginning of the tree. //! @@ -294,7 +300,7 @@ class avltree_impl //! //! Throws: Nothing. const_iterator cbegin() const - { return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); } + { return const_iterator (node_traits::get_left(this->priv_header_ptr()), this); } //! Effects: Returns an iterator pointing to the end of the tree. //! @@ -302,7 +308,7 @@ class avltree_impl //! //! Throws: Nothing. iterator end() - { return iterator (node_ptr(&priv_header()), this); } + { return iterator (this->priv_header_ptr(), this); } //! Effects: Returns a const_iterator pointing to the end of the tree. //! @@ -318,7 +324,7 @@ class avltree_impl //! //! Throws: Nothing. const_iterator cend() const - { return const_iterator (uncast(const_node_ptr(&priv_header())), this); } + { return const_iterator (uncast(this->priv_header_ptr()), this); } //! Effects: Returns a reverse_iterator pointing to the beginning of the //! reversed tree. @@ -432,7 +438,7 @@ class avltree_impl //! //! Throws: Nothing. bool empty() const - { return node_algorithms::unique(const_node_ptr(&priv_header())); } + { return node_algorithms::unique(this->priv_header_ptr()); } //! Effects: Returns the number of elements stored in the tree. //! @@ -445,7 +451,7 @@ class avltree_impl if(constant_time_size) return this->priv_size_traits().get_size(); else{ - return (size_type)node_algorithms::size(const_node_ptr(&priv_header())); + return (size_type)node_algorithms::size(this->priv_header_ptr()); } } @@ -460,7 +466,7 @@ class avltree_impl using std::swap; swap(priv_comp(), priv_comp()); //These can't throw - node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header())); + node_algorithms::swap_tree(this->priv_header_ptr(), other.priv_header_ptr()); 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()); @@ -487,7 +493,7 @@ class avltree_impl if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); iterator ret(node_algorithms::insert_equal_upper_bound - (node_ptr(&priv_header()), to_insert, key_node_comp), this); + (this->priv_header_ptr(), to_insert, key_node_comp), this); this->priv_size_traits().increment(); return ret; } @@ -514,7 +520,7 @@ class avltree_impl if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); iterator ret(node_algorithms::insert_equal - (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this); + (this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this); this->priv_size_traits().increment(); return ret; } @@ -650,7 +656,7 @@ class avltree_impl comp(key_value_comp, this); std::pair ret = (node_algorithms::insert_unique_check - (node_ptr(&priv_header()), key, comp, commit_data)); + (this->priv_header_ptr(), key, comp, commit_data)); return std::pair(iterator(ret.first, this), ret.second); } @@ -695,7 +701,7 @@ class avltree_impl comp(key_value_comp, this); std::pair ret = (node_algorithms::insert_unique_check - (node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data)); + (this->priv_header_ptr(), hint.pointed_node(), key, comp, commit_data)); return std::pair(iterator(ret.first, this), ret.second); } @@ -722,7 +728,7 @@ class avltree_impl if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); node_algorithms::insert_unique_commit - (node_ptr(&priv_header()), to_insert, commit_data); + (this->priv_header_ptr(), to_insert, commit_data); this->priv_size_traits().increment(); return iterator(to_insert, this); } @@ -747,7 +753,7 @@ class avltree_impl if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); iterator ret(node_algorithms::insert_before - (node_ptr(&priv_header()), pos.pointed_node(), to_insert), this); + (this->priv_header_ptr(), pos.pointed_node(), to_insert), this); this->priv_size_traits().increment(); return ret; } @@ -771,7 +777,7 @@ class avltree_impl node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); - node_algorithms::push_back(node_ptr(&priv_header()), to_insert); + node_algorithms::push_back(this->priv_header_ptr(), to_insert); this->priv_size_traits().increment(); } @@ -794,7 +800,7 @@ class avltree_impl node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert)); - node_algorithms::push_front(node_ptr(&priv_header()), to_insert); + node_algorithms::push_front(this->priv_header_ptr(), to_insert); this->priv_size_traits().increment(); } @@ -813,7 +819,7 @@ class avltree_impl node_ptr to_erase(i.pointed_node()); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase)); - node_algorithms::erase(&priv_header(), to_erase); + node_algorithms::erase(this->priv_header_ptr(), to_erase); this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); @@ -975,7 +981,7 @@ class avltree_impl this->clear_and_dispose(detail::null_disposer()); } else{ - node_algorithms::init_header(&priv_header()); + node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(0); } } @@ -992,9 +998,9 @@ class avltree_impl template void clear_and_dispose(Disposer disposer) { - node_algorithms::clear_and_dispose(node_ptr(&priv_header()) + node_algorithms::clear_and_dispose(this->priv_header_ptr() , detail::node_disposer(disposer, this)); - node_algorithms::init_header(&priv_header()); + node_algorithms::init_header(this->priv_header_ptr()); this->priv_size_traits().set_size(0); } @@ -1050,7 +1056,7 @@ class avltree_impl detail::key_nodeptr_comp key_node_comp(comp, this); return iterator(node_algorithms::lower_bound - (const_node_ptr(&priv_header()), key, key_node_comp), this); + (this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Returns a const iterator to the first element whose @@ -1065,7 +1071,7 @@ class avltree_impl detail::key_nodeptr_comp key_node_comp(comp, this); return const_iterator(node_algorithms::lower_bound - (const_node_ptr(&priv_header()), key, key_node_comp), this); + (this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Returns an iterator to the first element whose @@ -1090,7 +1096,7 @@ class avltree_impl detail::key_nodeptr_comp key_node_comp(comp, this); return iterator(node_algorithms::upper_bound - (const_node_ptr(&priv_header()), key, key_node_comp), this); + (this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Returns an iterator to the first element whose @@ -1115,7 +1121,7 @@ class avltree_impl detail::key_nodeptr_comp key_node_comp(comp, this); return const_iterator(node_algorithms::upper_bound - (const_node_ptr(&priv_header()), key, key_node_comp), this); + (this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Finds an iterator to the first element whose key is @@ -1139,7 +1145,7 @@ class avltree_impl detail::key_nodeptr_comp key_node_comp(comp, this); return iterator - (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + (node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Finds a const_iterator to the first element whose key is @@ -1163,7 +1169,7 @@ class avltree_impl detail::key_nodeptr_comp key_node_comp(comp, this); return const_iterator - (node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this); + (node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this); } //! Effects: Finds a range containing all elements whose key is k or @@ -1189,7 +1195,7 @@ class avltree_impl detail::key_nodeptr_comp key_node_comp(comp, this); std::pair ret - (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + (node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp)); return std::pair(iterator(ret.first, this), iterator(ret.second, this)); } @@ -1218,7 +1224,7 @@ class avltree_impl detail::key_nodeptr_comp key_node_comp(comp, this); std::pair ret - (node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp)); + (node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp)); return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); } @@ -1244,8 +1250,8 @@ class avltree_impl detail::exception_disposer rollback(*this, disposer); node_algorithms::clone - (const_node_ptr(&src.priv_header()) - ,node_ptr(&this->priv_header()) + (src.priv_header_ptr() + ,this->priv_header_ptr() ,detail::node_cloner(cloner, this) ,detail::node_disposer(disposer, this)); this->priv_size_traits().set_size(src.priv_size_traits().get_size()); @@ -1267,7 +1273,7 @@ class avltree_impl pointer unlink_leftmost_without_rebalance() { node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance - (node_ptr(&priv_header()))); + (this->priv_header_ptr())); if(!to_be_disposed) return 0; this->priv_size_traits().decrement(); @@ -1293,7 +1299,7 @@ class avltree_impl void replace_node(iterator replace_this, reference with_this) { node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) - , node_ptr(&priv_header()) + , this->priv_header_ptr() , get_real_value_traits().to_node_ptr(with_this)); if(safemode_or_autounlink) node_algorithms::init(replace_this.pointed_node()); @@ -1424,7 +1430,7 @@ class avltree_impl static avltree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { header_plus_size *r = detail::parent_from_member - ( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_size::header_); + ( boost::intrusive::detail::to_raw_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/avltree_algorithms.hpp b/include/boost/intrusive/avltree_algorithms.hpp index 7e0cd2e..9b917c7 100644 --- a/include/boost/intrusive/avltree_algorithms.hpp +++ b/include/boost/intrusive/avltree_algorithms.hpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace boost { @@ -88,7 +89,7 @@ class avltree_algorithms : base_t(f) {} - node_ptr operator()(node_ptr p) + node_ptr operator()(const node_ptr &p) { node_ptr n = base_t::get()(p); NodeTraits::set_balance(n, NodeTraits::get_balance(p)); @@ -98,21 +99,19 @@ class avltree_algorithms struct avltree_erase_fixup { - void operator()(node_ptr to_erase, node_ptr successor) + void operator()(const node_ptr &to_erase, const node_ptr &successor) { NodeTraits::set_balance(successor, NodeTraits::get_balance(to_erase)); } }; - static node_ptr uncast(const_node_ptr ptr) - { - return node_ptr(const_cast(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr))); - } + static node_ptr uncast(const const_node_ptr & ptr) + { return pointer_traits::const_cast_from(ptr); } /// @endcond public: - static node_ptr begin_node(const_node_ptr header) + static node_ptr begin_node(const const_node_ptr & header) { return tree_algorithms::begin_node(header); } - static node_ptr end_node(const_node_ptr header) + static node_ptr end_node(const const_node_ptr & header) { return tree_algorithms::end_node(header); } //! This type is the information that will be @@ -128,7 +127,7 @@ class avltree_algorithms //! Complexity: Constant. //! //! Throws: Nothing. - static void swap_tree(node_ptr header1, node_ptr header2) + static void swap_tree(const node_ptr & header1, const node_ptr & header2) { return tree_algorithms::swap_tree(header1, header2); } //! Requires: node1 and node2 can't be header nodes @@ -146,7 +145,7 @@ class avltree_algorithms //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function - static void swap_nodes(node_ptr node1, node_ptr node2) + static void swap_nodes(const node_ptr & node1, const node_ptr & node2) { if(node1 == node2) return; @@ -170,7 +169,7 @@ class avltree_algorithms //! node1 and node2 are not equivalent according to the ordering rules. //! //!Experimental function - static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) + static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2) { if(node1 == node2) return; @@ -197,7 +196,7 @@ class avltree_algorithms //! the node, since no rebalancing and comparison is needed. //! //!Experimental function - static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) + static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node) { if(node_to_be_replaced == new_node) return; @@ -220,7 +219,7 @@ class avltree_algorithms //! the node, since no rebalancing or comparison is needed. //! //!Experimental function - static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) + static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node) { tree_algorithms::replace_node(node_to_be_replaced, header, new_node); NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced)); @@ -233,7 +232,7 @@ class avltree_algorithms //! Complexity: Average complexity is constant time. //! //! Throws: Nothing. - static void unlink(node_ptr node) + static void unlink(const node_ptr & node) { node_ptr x = NodeTraits::get_parent(node); if(x){ @@ -256,7 +255,7 @@ class avltree_algorithms //! only be used for more unlink_leftmost_without_rebalance calls. //! This function is normally used to achieve a step by step //! controlled destruction of the tree. - static node_ptr unlink_leftmost_without_rebalance(node_ptr header) + static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header) { return tree_algorithms::unlink_leftmost_without_rebalance(header); } //! Requires: node is a node of the tree or an node initialized @@ -267,7 +266,7 @@ class avltree_algorithms //! Complexity: Constant time. //! //! Throws: Nothing. - static bool unique(const_node_ptr node) + static bool unique(const const_node_ptr & node) { return tree_algorithms::unique(node); } //! Requires: node is a node of the tree but it's not the header. @@ -277,7 +276,7 @@ class avltree_algorithms //! Complexity: Linear time. //! //! Throws: Nothing. - static std::size_t count(const_node_ptr node) + static std::size_t count(const const_node_ptr & node) { return tree_algorithms::count(node); } //! Requires: header is the header node of the tree. @@ -287,7 +286,7 @@ class avltree_algorithms //! Complexity: Linear time. //! //! Throws: Nothing. - static std::size_t size(const_node_ptr header) + static std::size_t size(const const_node_ptr & header) { return tree_algorithms::size(header); } //! Requires: p is a node from the tree except the header. @@ -297,7 +296,7 @@ class avltree_algorithms //! Complexity: Average constant time. //! //! Throws: Nothing. - static node_ptr next_node(node_ptr p) + static node_ptr next_node(const node_ptr & p) { return tree_algorithms::next_node(p); } //! Requires: p is a node from the tree except the leftmost node. @@ -307,7 +306,7 @@ class avltree_algorithms //! Complexity: Average constant time. //! //! Throws: Nothing. - static node_ptr prev_node(node_ptr p) + static node_ptr prev_node(const node_ptr & p) { return tree_algorithms::prev_node(p); } //! Requires: node must not be part of any tree. @@ -319,7 +318,7 @@ class avltree_algorithms //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. - static void init(node_ptr node) + static void init(const node_ptr & node) { tree_algorithms::init(node); } //! Requires: node must not be part of any tree. @@ -332,7 +331,7 @@ class avltree_algorithms //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. - static void init_header(node_ptr header) + static void init_header(const node_ptr & header) { tree_algorithms::init_header(header); NodeTraits::set_balance(header, NodeTraits::zero()); @@ -346,7 +345,7 @@ class avltree_algorithms //! Complexity: Amortized constant time. //! //! Throws: Nothing. - static node_ptr erase(node_ptr header, node_ptr z) + static node_ptr erase(const node_ptr & header, const node_ptr & z) { typename tree_algorithms::data_for_rebalance info; tree_algorithms::erase(header, z, avltree_erase_fixup(), info); @@ -363,13 +362,13 @@ class avltree_algorithms //! take a node_ptr and shouldn't throw. //! //! Effects: First empties target tree calling - //! void disposer::operator()(node_ptr) for every node of the tree + //! void disposer::operator()(const node_ptr &) for every node of the tree //! except the header. //! //! Then, duplicates the entire tree pointed by "source_header" cloning each - //! source node with node_ptr Cloner::operator()(node_ptr) to obtain + //! source node with node_ptr Cloner::operator()(const node_ptr &) to obtain //! the nodes of the target tree. If "cloner" throws, the cloned target nodes - //! are disposed using void disposer(node_ptr). + //! are disposed using void disposer(const node_ptr &). //! //! Complexity: Linear to the number of element of the source tree plus the. //! number of elements of tree target tree when calling this function. @@ -377,7 +376,7 @@ class avltree_algorithms //! Throws: If cloner functor throws. If this happens target nodes are disposed. template static void clone - (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer) + (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer) { avltree_node_cloner new_cloner(cloner); tree_algorithms::clone(source_header, target_header, new_cloner, disposer); @@ -387,7 +386,7 @@ class avltree_algorithms //! taking a node_ptr parameter and shouldn't throw. //! //! Effects: Empties the target tree calling - //! void disposer::operator()(node_ptr) for every node of the tree + //! void disposer::operator()(const node_ptr &) for every node of the tree //! except the header. //! //! Complexity: Linear to the number of element of the source tree plus the. @@ -395,7 +394,7 @@ class avltree_algorithms //! //! Throws: If cloner functor throws. If this happens target nodes are disposed. template - static void clear_and_dispose(node_ptr header, Disposer disposer) + static void clear_and_dispose(const node_ptr & header, Disposer disposer) { tree_algorithms::clear_and_dispose(header, disposer); } //! Requires: "header" must be the header node of a tree. @@ -412,7 +411,7 @@ class avltree_algorithms //! Throws: If "comp" throws. template static node_ptr lower_bound - (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::lower_bound(header, key, comp); } //! Requires: "header" must be the header node of a tree. @@ -428,7 +427,7 @@ class avltree_algorithms //! Throws: If "comp" throws. template static node_ptr upper_bound - (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::upper_bound(header, key, comp); } //! Requires: "header" must be the header node of a tree. @@ -444,7 +443,7 @@ class avltree_algorithms //! Throws: If "comp" throws. template static node_ptr find - (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::find(header, key, comp); } //! Requires: "header" must be the header node of a tree. @@ -462,7 +461,7 @@ class avltree_algorithms //! Throws: If "comp" throws. template static std::pair equal_range - (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp) + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::equal_range(header, key, comp); } //! Requires: "h" must be the header node of a tree. @@ -479,7 +478,7 @@ class avltree_algorithms //! Throws: If "comp" throws. template static node_ptr insert_equal_upper_bound - (node_ptr h, node_ptr new_node, NodePtrCompare comp) + (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) { tree_algorithms::insert_equal_upper_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); @@ -500,7 +499,7 @@ class avltree_algorithms //! Throws: If "comp" throws. template static node_ptr insert_equal_lower_bound - (node_ptr h, node_ptr new_node, NodePtrCompare comp) + (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp) { tree_algorithms::insert_equal_lower_bound(h, new_node, comp); rebalance_after_insertion(h, new_node); @@ -523,7 +522,7 @@ class avltree_algorithms //! Throws: If "comp" throws. template static node_ptr insert_equal - (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp) + (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp) { tree_algorithms::insert_equal(header, hint, new_node, comp); rebalance_after_insertion(header, new_node); @@ -545,7 +544,7 @@ class avltree_algorithms //! Note: If "pos" is not the successor of the newly inserted "new_node" //! tree invariants might be broken. static node_ptr insert_before - (node_ptr header, node_ptr pos, node_ptr new_node) + (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node) { tree_algorithms::insert_before(header, pos, new_node); rebalance_after_insertion(header, new_node); @@ -565,7 +564,7 @@ class avltree_algorithms //! Note: If "new_node" is less than the greatest inserted key //! tree invariants are broken. This function is slightly faster than //! using "insert_before". - static void push_back(node_ptr header, node_ptr new_node) + static void push_back(const node_ptr & header, const node_ptr & new_node) { tree_algorithms::push_back(header, new_node); rebalance_after_insertion(header, new_node); @@ -584,7 +583,7 @@ class avltree_algorithms //! Note: If "new_node" is greater than the lowest inserted key //! tree invariants are broken. This function is slightly faster than //! using "insert_before". - static void push_front(node_ptr header, node_ptr new_node) + static void push_front(const node_ptr & header, const node_ptr & new_node) { tree_algorithms::push_front(header, new_node); rebalance_after_insertion(header, new_node); @@ -626,7 +625,7 @@ class avltree_algorithms //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check - (const_node_ptr header, const KeyType &key + (const const_node_ptr & header, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { return tree_algorithms::insert_unique_check(header, key, comp, commit_data); } @@ -671,7 +670,7 @@ class avltree_algorithms //! if no more objects are inserted or erased from the set. template static std::pair insert_unique_check - (const_node_ptr header, node_ptr hint, const KeyType &key + (const const_node_ptr & header, const node_ptr &hint, const KeyType &key ,KeyNodePtrCompare comp, insert_commit_data &commit_data) { return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); } @@ -693,7 +692,7 @@ class avltree_algorithms //! previously executed to fill "commit_data". No value should be inserted or //! erased between the "insert_check" and "insert_commit" calls. static void insert_unique_commit - (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) + (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data) { tree_algorithms::insert_unique_commit(header, new_value, commit_data); rebalance_after_insertion(header, new_value); @@ -706,7 +705,7 @@ class avltree_algorithms //! Complexity: Logarithmic. //! //! Throws: Nothing. - static node_ptr get_header(node_ptr n) + static node_ptr get_header(const node_ptr & n) { return tree_algorithms::get_header(n); } /// @cond @@ -719,11 +718,12 @@ class avltree_algorithms //! Complexity: Constant. //! //! Throws: Nothing. - static bool is_header(const_node_ptr p) + static bool is_header(const const_node_ptr & p) { return NodeTraits::get_balance(p) == NodeTraits::zero() && tree_algorithms::is_header(p); } - static void rebalance_after_erasure(node_ptr header, node_ptr x, node_ptr x_parent) + static void rebalance_after_erasure(const node_ptr & header, const node_ptr & xnode, const node_ptr & xnode_parent) { + node_ptr x(xnode), x_parent(xnode_parent); for (node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)) { const balance x_parent_balance = NodeTraits::get_balance(x_parent); if(x_parent_balance == NodeTraits::zero()){ @@ -797,10 +797,10 @@ class avltree_algorithms } } - static void rebalance_after_insertion(node_ptr header, node_ptr x) + static void rebalance_after_insertion(const node_ptr & header, const node_ptr & xnode) { + node_ptr x(xnode); NodeTraits::set_balance(x, NodeTraits::zero()); - // Rebalance. for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){ const balance x_parent_balance = NodeTraits::get_balance(NodeTraits::get_parent(x)); @@ -843,7 +843,7 @@ class avltree_algorithms } } - static void left_right_balancing(node_ptr a, node_ptr b, node_ptr c) + static void left_right_balancing(const node_ptr & a, const node_ptr & b, const node_ptr & c) { // balancing... const balance c_balance = NodeTraits::get_balance(c); @@ -866,7 +866,7 @@ class avltree_algorithms } } - static void rotate_left_right(const node_ptr a, node_ptr hdr) + static void rotate_left_right(const node_ptr a, const node_ptr & hdr) { // | | // // a(-2) c // @@ -883,7 +883,7 @@ class avltree_algorithms left_right_balancing(a, b, c); } - static void rotate_right_left(const node_ptr a, node_ptr hdr) + static void rotate_right_left(const node_ptr a, const node_ptr & hdr) { // | | // // a(pos) c // @@ -900,7 +900,7 @@ class avltree_algorithms left_right_balancing(b, a, c); } - static void rotate_left(const node_ptr x, node_ptr hdr) + static void rotate_left(const node_ptr x, const node_ptr & hdr) { const node_ptr y = NodeTraits::get_right(x); tree_algorithms::rotate_left(x, hdr); @@ -916,7 +916,7 @@ class avltree_algorithms } } - static void rotate_right(const node_ptr x, node_ptr hdr) + static void rotate_right(const node_ptr x, const node_ptr & hdr) { const node_ptr y = NodeTraits::get_left(x); tree_algorithms::rotate_right(x, hdr); diff --git a/include/boost/intrusive/circular_list_algorithms.hpp b/include/boost/intrusive/circular_list_algorithms.hpp index 16b1971..c5de423 100644 --- a/include/boost/intrusive/circular_list_algorithms.hpp +++ b/include/boost/intrusive/circular_list_algorithms.hpp @@ -61,10 +61,10 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void init(node_ptr this_node) + static void init(const node_ptr &this_node) { - NodeTraits::set_next(this_node, node_ptr(0)); - NodeTraits::set_previous(this_node, node_ptr(0)); + NodeTraits::set_next(this_node, node_ptr()); + NodeTraits::set_previous(this_node, node_ptr()); } //! Effects: Returns true is "this_node" is in a non-used state @@ -73,7 +73,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static bool inited(const_node_ptr this_node) + static bool inited(const const_node_ptr &this_node) { return !NodeTraits::get_next(this_node); } //! Effects: Constructs an empty list, making this_node the only @@ -84,7 +84,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void init_header(node_ptr this_node) + static void init_header(const node_ptr &this_node) { NodeTraits::set_next(this_node, this_node); NodeTraits::set_previous(this_node, this_node); @@ -99,7 +99,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static bool unique(const_node_ptr this_node) + static bool unique(const const_node_ptr &this_node) { node_ptr next = NodeTraits::get_next(this_node); return !next || next == this_node; @@ -113,7 +113,7 @@ class circular_list_algorithms //! Complexity: Linear //! //! Throws: Nothing. - static std::size_t count(const_node_ptr this_node) + static std::size_t count(const const_node_ptr &this_node) { std::size_t result = 0; const_node_ptr p = this_node; @@ -131,10 +131,10 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static node_ptr unlink(node_ptr this_node) + static node_ptr unlink(const node_ptr &this_node) { - if(NodeTraits::get_next(this_node)){ - node_ptr next(NodeTraits::get_next(this_node)); + node_ptr next(NodeTraits::get_next(this_node)); + if(next){ node_ptr prev(NodeTraits::get_previous(this_node)); NodeTraits::set_next(prev, next); NodeTraits::set_previous(next, prev); @@ -152,7 +152,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void unlink(node_ptr b, node_ptr e) + static void unlink(const node_ptr &b, const node_ptr &e) { if (b != e) { node_ptr prevb(NodeTraits::get_previous(b)); @@ -168,13 +168,16 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void link_before(node_ptr nxt_node, node_ptr this_node) + static void link_before(const node_ptr &nxt_node, const node_ptr &this_node) { node_ptr prev(NodeTraits::get_previous(nxt_node)); NodeTraits::set_previous(this_node, prev); - NodeTraits::set_next(prev, this_node); - NodeTraits::set_previous(nxt_node, this_node); NodeTraits::set_next(this_node, nxt_node); + //nxt_node might be an alias for prev->next_ + //so use it before update it before NodeTraits::set_next(prev, ...) + //is called and the reference changes it's value + NodeTraits::set_previous(nxt_node, this_node); + NodeTraits::set_next(prev, this_node); } //! Requires: prev_node must be a node of a circular list. @@ -184,13 +187,16 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void link_after(node_ptr prev_node, node_ptr this_node) + static void link_after(const node_ptr &prev_node, const node_ptr &this_node) { node_ptr next(NodeTraits::get_next(prev_node)); NodeTraits::set_previous(this_node, prev_node); NodeTraits::set_next(this_node, next); - NodeTraits::set_previous(next, this_node); + //prev_node might be an alias for next->next_ + //so use it before update it before NodeTraits::set_previous(next, ...) + //is called and the reference changes it's value NodeTraits::set_next(prev_node, this_node); + NodeTraits::set_previous(next, this_node); } //! Requires: this_node and other_node must be nodes inserted @@ -204,7 +210,7 @@ class circular_list_algorithms //! //! Throws: Nothing. /* - static void swap_nodes(node_ptr this_node, node_ptr other_node) + static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node) { if (other_node == this_node) @@ -243,13 +249,13 @@ class circular_list_algorithms //Watanabe version private: - static void swap_prev(node_ptr this_node, node_ptr other_node) + static void swap_prev(const node_ptr &this_node, const node_ptr &other_node) { node_ptr temp(NodeTraits::get_previous(this_node)); NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node)); NodeTraits::set_previous(other_node, temp); } - static void swap_next(node_ptr this_node, node_ptr other_node) + static void swap_next(const node_ptr &this_node, const node_ptr &other_node) { node_ptr temp(NodeTraits::get_next(this_node)); NodeTraits::set_next(this_node, NodeTraits::get_next(other_node)); @@ -257,7 +263,7 @@ class circular_list_algorithms } public: - static void swap_nodes(node_ptr this_node, node_ptr other_node) + static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node) { if (other_node == this_node) return; @@ -298,7 +304,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void transfer(node_ptr p, node_ptr b, node_ptr e) + static void transfer(const node_ptr &p, const node_ptr &b, const node_ptr &e) { if (b != e) { node_ptr prev_p(NodeTraits::get_previous(p)); @@ -323,7 +329,7 @@ class circular_list_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void transfer(node_ptr p, node_ptr i) + static void transfer(const node_ptr &p, const node_ptr &i) { node_ptr n(NodeTraits::get_next(i)); if(n != p && i != p){ @@ -344,7 +350,7 @@ class circular_list_algorithms //! Throws: Nothing. //! //! Complexity: This function is linear time. - static void reverse(node_ptr p) + static void reverse(const node_ptr &p) { node_ptr f(NodeTraits::get_next(p)); node_ptr i(NodeTraits::get_next(f)), e(p); @@ -362,7 +368,7 @@ class circular_list_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of moved positions. - static void move_backwards(node_ptr p, std::size_t n) + static void move_backwards(const node_ptr &p, std::size_t n) { //Null shift, nothing to do if(!n) return; @@ -382,7 +388,7 @@ class circular_list_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of moved positions. - static void move_forward(node_ptr p, std::size_t n) + static void move_forward(const node_ptr &p, std::size_t n) { //Null shift, nothing to do if(!n) return; diff --git a/include/boost/intrusive/circular_slist_algorithms.hpp b/include/boost/intrusive/circular_slist_algorithms.hpp index 8bb95cd..7cb8f5b 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) == node_ptr() //! //! Complexity: Constant //! @@ -74,9 +74,9 @@ class circular_slist_algorithms //! //! Effects: Returns true is "this_node" is the only node of a circular list: //! or it's a not inserted node: - //! return !NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node + //! return false == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node //! - //! Complexity: Constant + //! Complexity: Constant //! //! Throws: Nothing. static bool unique(const_node_ptr this_node); @@ -137,7 +137,7 @@ class circular_slist_algorithms //! Complexity: Constant //! //! Throws: Nothing. - static void init_header(node_ptr this_node) + static void init_header(const node_ptr &this_node) { NodeTraits::set_next(this_node, this_node); } //! Requires: this_node and prev_init_node must be in the same circular list. @@ -149,7 +149,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements between prev_init_node and this_node. //! //! Throws: Nothing. - static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node) + static node_ptr get_previous_node(const node_ptr &prev_init_node, const node_ptr &this_node) { return base_t::get_previous_node(prev_init_node, this_node); } //! Requires: this_node must be in a circular list or be an empty circular list. @@ -159,7 +159,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list. //! //! Throws: Nothing. - static node_ptr get_previous_node(node_ptr this_node) + static node_ptr get_previous_node(const node_ptr & this_node) { return base_t::get_previous_node(this_node, this_node); } //! Requires: this_node must be in a circular list or be an empty circular list. @@ -169,7 +169,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list. //! //! Throws: Nothing. - static node_ptr get_previous_previous_node(node_ptr this_node) + static node_ptr get_previous_previous_node(const node_ptr & this_node) { return get_previous_previous_node(this_node, this_node); } //! Requires: this_node and prev_prev_init_node must be in the same circular list. @@ -181,7 +181,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list. //! //! Throws: Nothing. - static node_ptr get_previous_previous_node(node_ptr prev_prev_init_node, node_ptr this_node) + static node_ptr get_previous_previous_node(const node_ptr & prev_prev_init_node, const node_ptr & this_node) { node_ptr p = prev_prev_init_node; node_ptr p_next = NodeTraits::get_next(p); @@ -202,7 +202,7 @@ class circular_slist_algorithms //! Complexity: Linear //! //! Throws: Nothing. - static std::size_t count(const_node_ptr this_node) + static std::size_t count(const const_node_ptr & this_node) { std::size_t result = 0; const_node_ptr p = this_node; @@ -220,7 +220,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list //! //! Throws: Nothing. - static void unlink(node_ptr this_node) + static void unlink(const node_ptr & this_node) { if(NodeTraits::get_next(this_node)) base_t::unlink_after(get_previous_node(this_node)); @@ -233,7 +233,7 @@ class circular_slist_algorithms //! Complexity: Linear to the number of elements in the circular list. //! //! Throws: Nothing. - static void link_before (node_ptr nxt_node, node_ptr this_node) + static void link_before (const node_ptr & nxt_node, const node_ptr & this_node) { base_t::link_after(get_previous_node(nxt_node), this_node); } //! Requires: this_node and other_node must be nodes inserted @@ -246,7 +246,7 @@ class circular_slist_algorithms //! Complexity: Linear to number of elements of both lists //! //! Throws: Nothing. - static void swap_nodes(node_ptr this_node, node_ptr other_node) + static void swap_nodes(const node_ptr & this_node, const node_ptr & other_node) { if (other_node == this_node) return; @@ -284,7 +284,7 @@ class circular_slist_algorithms //! Throws: Nothing. //! //! Complexity: This function is linear to the contained elements. - static void reverse(node_ptr p) + static void reverse(const node_ptr & p) { node_ptr i = NodeTraits::get_next(p), e(p); for (;;) { @@ -303,18 +303,18 @@ class circular_slist_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of elements plus the number moved positions. - static node_ptr move_backwards(node_ptr p, std::size_t n) + static node_ptr move_backwards(const node_ptr & p, std::size_t n) { //Null shift, nothing to do - if(!n) return node_ptr(0); + if(!n) return node_ptr(); node_ptr first = NodeTraits::get_next(p); //count() == 1 or 2, nothing to do if(NodeTraits::get_next(first) == p) - return node_ptr(0); + return node_ptr(); bool end_found = false; - node_ptr new_last(0); + node_ptr new_last = node_ptr(); //Now find the new last node according to the shift count. //If we find p before finding the new last node @@ -327,7 +327,7 @@ class circular_slist_algorithms //Shortcut the shift with the modulo of the size of the list n %= i; if(!n) - return node_ptr(0); + return node_ptr(); i = 0; //Unlink p and continue the new first node search first = NodeTraits::get_next(p); @@ -355,14 +355,14 @@ class circular_slist_algorithms //! Throws: Nothing. //! //! Complexity: Linear to the number of elements plus the number moved positions. - static node_ptr move_forward(node_ptr p, std::size_t n) + static node_ptr move_forward(const node_ptr & p, std::size_t n) { //Null shift, nothing to do - if(!n) return node_ptr(0); + if(!n) return node_ptr(); node_ptr first = node_traits::get_next(p); //count() == 1 or 2, nothing to do - if(node_traits::get_next(first) == p) return node_ptr(0); + if(node_traits::get_next(first) == p) return node_ptr(); //Iterate until p is found to know where the current last node is. //If the shift count is less than the size of the list, we can also obtain @@ -381,7 +381,7 @@ class circular_slist_algorithms //Shortcut the shift with the modulo of the size of the list std::size_t new_before_last_pos = (distance - (n % distance))% distance; //If the shift is a multiple of the size there is nothing to do - if(!new_before_last_pos) return node_ptr(0); + if(!new_before_last_pos) return node_ptr(); for( new_last = p ; new_before_last_pos-- diff --git a/include/boost/intrusive/derivation_value_traits.hpp b/include/boost/intrusive/derivation_value_traits.hpp index 8711d56..fb5d8ae 100644 --- a/include/boost/intrusive/derivation_value_traits.hpp +++ b/include/boost/intrusive/derivation_value_traits.hpp @@ -34,8 +34,10 @@ struct derivation_value_traits 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; + typedef typename boost::intrusive:: + pointer_traits::reference reference; + typedef typename boost::intrusive:: + pointer_traits::reference const_reference; static const link_mode_type link_mode = LinkMode; static node_ptr to_node_ptr(reference value) @@ -44,7 +46,7 @@ struct derivation_value_traits static const_node_ptr to_node_ptr(const_reference value) { return node_ptr(&value); } - static pointer to_value_ptr(node_ptr n) + static pointer to_value_ptr(const node_ptr &n) { // This still fails in gcc < 4.4 so forget about it // using ::boost::static_pointer_cast; @@ -52,7 +54,7 @@ struct derivation_value_traits return pointer(&static_cast(*n)); } - static const_pointer to_value_ptr(const_node_ptr n) + static const_pointer to_value_ptr(const const_node_ptr &n) { // This still fails in gcc < 4.4 so forget about it // using ::boost::static_pointer_cast; diff --git a/include/boost/intrusive/detail/any_node_and_algorithms.hpp b/include/boost/intrusive/detail/any_node_and_algorithms.hpp index 513bdd9..bda9ad3 100644 --- a/include/boost/intrusive/detail/any_node_and_algorithms.hpp +++ b/include/boost/intrusive/detail/any_node_and_algorithms.hpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -27,8 +27,8 @@ namespace intrusive { template struct any_node { - typedef typename boost::pointer_to_other - ::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type node_ptr; node_ptr node_ptr_1; node_ptr node_ptr_2; node_ptr node_ptr_3; @@ -39,21 +39,21 @@ template struct any_list_node_traits { typedef any_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type const_node_ptr; - static node_ptr get_next(const_node_ptr n) + static const node_ptr &get_next(const const_node_ptr & n) { return n->node_ptr_1; } - static void set_next(node_ptr n, node_ptr next) + static void set_next(const node_ptr & n, const node_ptr & next) { n->node_ptr_1 = next; } - static node_ptr get_previous(const_node_ptr n) + static const node_ptr &get_previous(const const_node_ptr & n) { return n->node_ptr_2; } - static void set_previous(node_ptr n, node_ptr prev) + static void set_previous(const node_ptr & n, const node_ptr & prev) { n->node_ptr_2 = prev; } }; @@ -62,15 +62,15 @@ template struct any_slist_node_traits { typedef any_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type const_node_ptr; - static node_ptr get_next(const_node_ptr n) + static const node_ptr &get_next(const const_node_ptr & n) { return n->node_ptr_1; } - static void set_next(node_ptr n, node_ptr next) + static void set_next(const node_ptr & n, const node_ptr & next) { n->node_ptr_1 = next; } }; @@ -87,25 +87,22 @@ struct any_unordered_node_traits static const bool store_hash = true; static const bool optimize_multikey = true; - static node_ptr get_next(const_node_ptr n) - { - using ::boost::static_pointer_cast; - return static_pointer_cast(n->node_ptr_1); - } + static const node_ptr &get_next(const const_node_ptr & n) + { return n->node_ptr_1; } - static void set_next(node_ptr n, node_ptr next) + static void set_next(const node_ptr & n, const node_ptr & next) { n->node_ptr_1 = next; } - static node_ptr get_prev_in_group(const_node_ptr n) + static node_ptr get_prev_in_group(const const_node_ptr & n) { return n->node_ptr_2; } - static void set_prev_in_group(node_ptr n, node_ptr prev) + static void set_prev_in_group(const node_ptr & n, const node_ptr & prev) { n->node_ptr_2 = prev; } - static std::size_t get_hash(const_node_ptr n) + static std::size_t get_hash(const const_node_ptr & n) { return n->size_t_1; } - static void set_hash(node_ptr n, std::size_t h) + static void set_hash(const node_ptr & n, std::size_t h) { n->size_t_1 = h; } }; @@ -115,35 +112,35 @@ struct any_rbtree_node_traits { typedef any_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type const_node_ptr; typedef std::size_t color; - static node_ptr get_parent(const_node_ptr n) + static const node_ptr &get_parent(const const_node_ptr & n) { return n->node_ptr_1; } - static void set_parent(node_ptr n, node_ptr p) + static void set_parent(const node_ptr & n, const node_ptr & p) { n->node_ptr_1 = p; } - static node_ptr get_left(const_node_ptr n) + static const node_ptr &get_left(const const_node_ptr & n) { return n->node_ptr_2; } - static void set_left(node_ptr n, node_ptr l) + static void set_left(const node_ptr & n, const node_ptr & l) { n->node_ptr_2 = l; } - static node_ptr get_right(const_node_ptr n) + static const node_ptr &get_right(const const_node_ptr & n) { return n->node_ptr_3; } - static void set_right(node_ptr n, node_ptr r) + static void set_right(const node_ptr & n, const node_ptr & r) { n->node_ptr_3 = r; } - static color get_color(const_node_ptr n) + static color get_color(const const_node_ptr & n) { return n->size_t_1; } - static void set_color(node_ptr n, color c) + static void set_color(const node_ptr & n, color c) { n->size_t_1 = c; } static color black() @@ -159,34 +156,34 @@ struct any_avltree_node_traits { typedef any_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type const_node_ptr; typedef std::size_t balance; - static node_ptr get_parent(const_node_ptr n) + static const node_ptr &get_parent(const const_node_ptr & n) { return n->node_ptr_1; } - static void set_parent(node_ptr n, node_ptr p) + static void set_parent(const node_ptr & n, const node_ptr & p) { n->node_ptr_1 = p; } - static node_ptr get_left(const_node_ptr n) + static const node_ptr &get_left(const const_node_ptr & n) { return n->node_ptr_2; } - static void set_left(node_ptr n, node_ptr l) + static void set_left(const node_ptr & n, const node_ptr & l) { n->node_ptr_2 = l; } - static node_ptr get_right(const_node_ptr n) + static const node_ptr &get_right(const const_node_ptr & n) { return n->node_ptr_3; } - static void set_right(node_ptr n, node_ptr r) + static void set_right(const node_ptr & n, const node_ptr & r) { n->node_ptr_3 = r; } - static balance get_balance(const_node_ptr n) + static balance get_balance(const const_node_ptr & n) { return n->size_t_1; } - static void set_balance(node_ptr n, balance b) + static void set_balance(const node_ptr & n, balance b) { n->size_t_1 = b; } static balance negative() @@ -205,27 +202,27 @@ struct any_tree_node_traits { typedef any_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type const_node_ptr; - static node_ptr get_parent(const_node_ptr n) + static const node_ptr &get_parent(const const_node_ptr & n) { return n->node_ptr_1; } - static void set_parent(node_ptr n, node_ptr p) + static void set_parent(const node_ptr & n, const node_ptr & p) { n->node_ptr_1 = p; } - static node_ptr get_left(const_node_ptr n) + static const node_ptr &get_left(const const_node_ptr & n) { return n->node_ptr_2; } - static void set_left(node_ptr n, node_ptr l) + static void set_left(const node_ptr & n, const node_ptr & l) { n->node_ptr_2 = l; } - static node_ptr get_right(const_node_ptr n) + static const node_ptr &get_right(const const_node_ptr & n) { return n->node_ptr_3; } - static void set_right(node_ptr n, node_ptr r) + static void set_right(const node_ptr & n, const node_ptr & r) { n->node_ptr_3 = r; } }; @@ -234,10 +231,10 @@ class any_node_traits { public: typedef any_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type const_node_ptr; }; template @@ -249,10 +246,10 @@ class any_algorithms public: typedef any_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer::type const_node_ptr; typedef any_node_traits node_traits; //! Requires: node must not be part of any tree. @@ -264,7 +261,7 @@ class any_algorithms //! Throws: Nothing. //! //! Nodes: If node is inserted in a tree, this function corrupts the tree. - static void init(node_ptr node) + static void init(const node_ptr & node) { node->node_ptr_1 = 0; }; //! Effects: Returns true if node is in the same state as if called init(node) @@ -272,19 +269,19 @@ class any_algorithms //! Complexity: Constant. //! //! Throws: Nothing. - static bool inited(const_node_ptr node) + static bool inited(const const_node_ptr & node) { return !node->node_ptr_1; }; - static bool unique(const_node_ptr node) + static bool unique(const const_node_ptr & node) { return 0 == node->node_ptr_1; } - static void unlink(node_ptr) + static void unlink(const node_ptr &) { //Auto-unlink hooks and unlink() are not available for any hooks any_algorithms::template function_not_available_for_any_hooks(); } - static void swap_nodes(node_ptr l, node_ptr r) + static void swap_nodes(const node_ptr & l, const node_ptr & r) { //Any nodes have no swap_nodes capability because they don't know //what algorithm they must use to unlink the node from the container diff --git a/include/boost/intrusive/detail/avltree_node.hpp b/include/boost/intrusive/detail/avltree_node.hpp index 92458a4..dc600e6 100644 --- a/include/boost/intrusive/detail/avltree_node.hpp +++ b/include/boost/intrusive/detail/avltree_node.hpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include @@ -33,9 +33,9 @@ namespace intrusive { template struct compact_avltree_node { - typedef typename pointer_to_other - >::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer + >::type node_ptr; enum balance { negative_t, zero_t, positive_t }; node_ptr parent_, left_, right_; }; @@ -44,9 +44,9 @@ struct compact_avltree_node template struct avltree_node { - typedef typename pointer_to_other - >::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer + >::type node_ptr; enum balance { negative_t, zero_t, positive_t }; node_ptr parent_, left_, right_; balance balance_; @@ -59,34 +59,37 @@ struct default_avltree_node_traits_impl { typedef avltree_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + ::template rebind_pointer + ::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer + ::type const_node_ptr; + typedef typename node::balance balance; - static node_ptr get_parent(const_node_ptr n) + static const node_ptr & get_parent(const const_node_ptr & n) { return n->parent_; } - static void set_parent(node_ptr n, node_ptr p) + static void set_parent(const node_ptr & n, const node_ptr & p) { n->parent_ = p; } - static node_ptr get_left(const_node_ptr n) + static const node_ptr & get_left(const const_node_ptr & n) { return n->left_; } - static void set_left(node_ptr n, node_ptr l) + static void set_left(const node_ptr & n, const node_ptr & l) { n->left_ = l; } - static node_ptr get_right(const_node_ptr n) + static const node_ptr & get_right(const const_node_ptr & n) { return n->right_; } - static void set_right(node_ptr n, node_ptr r) + static void set_right(const node_ptr & n, const node_ptr & r) { n->right_ = r; } - static balance get_balance(const_node_ptr n) + static balance get_balance(const const_node_ptr & n) { return n->balance_; } - static void set_balance(node_ptr n, balance b) + static void set_balance(const node_ptr & n, balance b) { n->balance_ = b; } static balance negative() @@ -105,36 +108,39 @@ template struct compact_avltree_node_traits_impl { typedef compact_avltree_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + + typedef typename pointer_traits + ::template rebind_pointer + ::type node_ptr; + typedef typename pointer_traits + ::template rebind_pointer + ::type const_node_ptr; typedef typename node::balance balance; typedef pointer_plus_bits ptr_bit; - static node_ptr get_parent(const_node_ptr n) + static node_ptr get_parent(const const_node_ptr & n) { return ptr_bit::get_pointer(n->parent_); } - static void set_parent(node_ptr n, node_ptr p) + static void set_parent(const node_ptr & n, const node_ptr & p) { ptr_bit::set_pointer(n->parent_, p); } - static node_ptr get_left(const_node_ptr n) + static const node_ptr & get_left(const const_node_ptr & n) { return n->left_; } - static void set_left(node_ptr n, node_ptr l) + static void set_left(const node_ptr & n, const node_ptr & l) { n->left_ = l; } - static node_ptr get_right(const_node_ptr n) + static const node_ptr & get_right(const const_node_ptr & n) { return n->right_; } - static void set_right(node_ptr n, node_ptr r) + static void set_right(const node_ptr & n, const node_ptr & r) { n->right_ = r; } - static balance get_balance(const_node_ptr n) + static balance get_balance(const const_node_ptr & n) { return (balance)ptr_bit::get_bits(n->parent_); } - static void set_balance(node_ptr n, balance b) + static void set_balance(const node_ptr & n, balance b) { ptr_bit::set_bits(n->parent_, (std::size_t)b); } static balance negative() diff --git a/include/boost/intrusive/detail/common_slist_algorithms.hpp b/include/boost/intrusive/detail/common_slist_algorithms.hpp index c6bdb20..15d6b3f 100644 --- a/include/boost/intrusive/detail/common_slist_algorithms.hpp +++ b/include/boost/intrusive/detail/common_slist_algorithms.hpp @@ -31,7 +31,7 @@ class common_slist_algorithms typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef NodeTraits node_traits; - static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node) + static node_ptr get_previous_node(const node_ptr & prev_init_node, const node_ptr & this_node) { node_ptr p = prev_init_node; for( node_ptr p_next @@ -44,44 +44,44 @@ class common_slist_algorithms return p; } - static void init_header(node_ptr this_node) + static void init_header(const node_ptr & this_node) { NodeTraits::set_next(this_node, this_node); } - static void init(node_ptr this_node) - { NodeTraits::set_next(this_node, node_ptr(0)); } + static void init(const node_ptr & this_node) + { NodeTraits::set_next(this_node, node_ptr()); } - static bool unique(const_node_ptr this_node) + static bool unique(const const_node_ptr & this_node) { node_ptr next = NodeTraits::get_next(this_node); return !next || next == this_node; } - static bool inited(const_node_ptr this_node) + static bool inited(const const_node_ptr & this_node) { return !NodeTraits::get_next(this_node); } - static void unlink_after(node_ptr prev_node) + static void unlink_after(const node_ptr & prev_node) { - node_ptr this_node(NodeTraits::get_next(prev_node)); + const_node_ptr this_node(NodeTraits::get_next(prev_node)); NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node)); } - static void unlink_after(node_ptr prev_node, node_ptr last_node) + static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node) { NodeTraits::set_next(prev_node, last_node); } - static void link_after(node_ptr prev_node, node_ptr this_node) + static void link_after(const node_ptr & prev_node, const node_ptr & this_node) { NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node)); NodeTraits::set_next(prev_node, this_node); } - static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be) + static void incorporate_after(const node_ptr & bp, const node_ptr & b, const node_ptr & be) { node_ptr p(NodeTraits::get_next(bp)); NodeTraits::set_next(bp, b); NodeTraits::set_next(be, p); } - static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be) + static void transfer_after(const node_ptr & bp, const node_ptr & bb, const node_ptr & be) { if (bp != bb && bp != be && bb != be) { node_ptr next_b = NodeTraits::get_next(bb); diff --git a/include/boost/intrusive/detail/function_detector.hpp b/include/boost/intrusive/detail/function_detector.hpp index a20db6d..e00a7ef 100644 --- a/include/boost/intrusive/detail/function_detector.hpp +++ b/include/boost/intrusive/detail/function_detector.hpp @@ -11,6 +11,7 @@ ///////////////////////////////////////////////////////////////////////////// // This code was modified from the code posted by Alexandre Courpron in his // article "Interface Detection" in The Code Project: +// http://www.codeproject.com/KB/architecture/Detector.aspx /////////////////////////////////////////////////////////////////////////////// // Copyright 2007 Alexandre Courpron // diff --git a/include/boost/intrusive/detail/generic_hook.hpp b/include/boost/intrusive/detail/generic_hook.hpp index ae1282e..fc35610 100644 --- a/include/boost/intrusive/detail/generic_hook.hpp +++ b/include/boost/intrusive/detail/generic_hook.hpp @@ -15,10 +15,11 @@ #include #include -#include +#include #include #include #include +#include #include namespace boost { @@ -146,20 +147,26 @@ class generic_hook (int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link; }; + node_ptr this_ptr() + { return pointer_traits::pointer_to(static_cast(*this)); } + + const_node_ptr this_ptr() const + { return pointer_traits::pointer_to(static_cast(*this)); } + public: /// @endcond generic_hook() { if(boost_intrusive_tags::safemode_or_autounlink){ - node_algorithms::init(static_cast(this)); + node_algorithms::init(this->this_ptr()); } } generic_hook(const generic_hook& ) { if(boost_intrusive_tags::safemode_or_autounlink){ - node_algorithms::init(static_cast(this)); + node_algorithms::init(this->this_ptr()); } } @@ -175,22 +182,21 @@ class generic_hook void swap_nodes(generic_hook &other) { node_algorithms::swap_nodes - ( static_cast(this), static_cast(&other)); + (this->this_ptr(), other.this_ptr()); } bool is_linked() const { //is_linked() can be only used in safe-mode or auto-unlink BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink )); - return !node_algorithms::unique - (static_cast(this)); + return !node_algorithms::unique(this->this_ptr()); } void unlink() { BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink )); - node_algorithms::unlink(static_cast(this)); - node_algorithms::init(static_cast(this)); + node_algorithms::unlink(this->this_ptr()); + node_algorithms::init(this->this_ptr()); } }; diff --git a/include/boost/intrusive/detail/has_member_function_callable_with.hpp b/include/boost/intrusive/detail/has_member_function_callable_with.hpp new file mode 100644 index 0000000..895b02a --- /dev/null +++ b/include/boost/intrusive/detail/has_member_function_callable_with.hpp @@ -0,0 +1,334 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2011-2011. 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. +// +////////////////////////////////////////////////////////////////////////////// + +// sample.h + +#if !BOOST_PP_IS_ITERATING + + #ifndef BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED + #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED + + #include + #include + #include + #include + #include + + namespace boost_intrusive_has_member_function_callable_with { + + struct dont_care + { + dont_care(...); + }; + + struct private_type + { + static private_type p; + private_type const &operator,(int) const; + }; + + typedef char yes_type; // sizeof(yes_type) == 1 + struct no_type{ char dummy[2]; }; // sizeof(no_type) == 2 + + template + no_type is_private_type(T const &); + yes_type is_private_type(private_type const &); + + } //boost_intrusive_has_member_function_callable_with + + #include + + #endif //BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED + +#else //!BOOST_PP_IS_ITERATING + + #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME not defined!" + #endif + + #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN not defined!" + #endif + + #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!" + #endif + + #if BOOST_PP_ITERATION_START() != 0 + #error "BOOST_PP_ITERATION_START() must be zero (0)" + #endif + + #if BOOST_PP_ITERATION() == 0 + + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN + + template + class BOOST_PP_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + struct BaseMixin + { + void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(); + }; + + struct Base : public Type, public BaseMixin { Base(); }; + template class Helper{}; + + template + static boost_intrusive_has_member_function_callable_with::no_type deduce + (U*, Helper* = 0); + static boost_intrusive_has_member_function_callable_with::yes_type deduce(...); + + public: + static const bool value = + sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0))); + }; + + #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) + + template + struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl); + //! + + template + struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) + + { + static const bool value = false; + }; + //! + + #if !defined(_MSC_VER) || (_MSC_VER != 1600) + + //Special case for 0 args + template< class F + , std::size_t N = + sizeof((boost::move_detail::declval(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))> + struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + boost_intrusive_has_member_function_callable_with::yes_type dummy; + BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int); + }; + + //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not + //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. + template + struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + boost_intrusive_has_member_function_callable_with::no_type dummy; + BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int); + }; + + template + struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) + + { + template + static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); + + template + static boost_intrusive_has_member_function_callable_with::no_type Test(...); + + static const bool value = sizeof(Test< Fun >(0)) + == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); + }; + + #else //#if !defined(_MSC_VER) || (_MSC_VER != 1600) + template + struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) + + { + template + static decltype( boost::move_detail::declval().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + , boost_intrusive_has_member_function_callable_with::yes_type()) + Test(Fun*); + + template + static boost_intrusive_has_member_function_callable_with::no_type Test(...); + + static const bool value = sizeof(Test(0)) + == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); + }; + #endif //#if !defined(_MSC_VER) || (_MSC_VER != 1600) + + #else //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) + + template + struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl); + + template + struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) + + { + static const bool value = false; + }; + + //Special case for 0 args + template< class F + , std::size_t N = + sizeof((boost::move_detail::declval(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))> + struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + boost_intrusive_has_member_function_callable_with::yes_type dummy; + BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int); + }; + + //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not + //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0. + template + struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + boost_intrusive_has_member_function_callable_with::no_type dummy; + BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int); + }; + + template + struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) + + { + template + static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); + + template + static boost_intrusive_has_member_function_callable_with::no_type Test(...); + + static const bool value = sizeof(Test< Fun >(0)) + == sizeof(boost_intrusive_has_member_function_callable_with::yes_type); + }; + + template + struct BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME ) + : Fun + { + BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )(); + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; + + boost_intrusive_has_member_function_callable_with::private_type + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + ( DontCares...) const; + }; + + template + struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) + + { + template + struct make_dontcare + { + typedef boost_intrusive_has_member_function_callable_with::dont_care type; + }; + + typedef BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME ) + ::type...> FunWrap; + + static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == + sizeof(boost_intrusive_has_member_function_callable_with::is_private_type + ( (::boost::move_detail::declval< FunWrap >(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + ( ::boost::move_detail::declval()... ), 0) ) + ) + ); + }; + + template + struct BOOST_PP_CAT( has_member_function_callable_with_ + , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_ + , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) + < Fun + , BOOST_PP_CAT( has_member_function_named_ + , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )::value + , Args... > + {}; + + #endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) + + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + + #else //BOOST_PP_ITERATION() == 0 + + #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) + + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN + + template + struct BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION()) + , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)) + : Fun + { + BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION()) + , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME))(); + + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; + boost_intrusive_has_member_function_callable_with::private_type + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + ( BOOST_PP_ENUM(BOOST_PP_ITERATION() + , BOOST_INTRUSIVE_PP_IDENTITY + , boost_intrusive_has_member_function_callable_with::dont_care)) const; + }; + + template + struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_ + , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl) + + { + typedef BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION()) + , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)) + FunWrap; + static bool const value = + (sizeof(boost_intrusive_has_member_function_callable_with::no_type) == + sizeof(boost_intrusive_has_member_function_callable_with::is_private_type + ( (boost::move_detail::declval(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + ( BOOST_PP_ENUM( BOOST_PP_ITERATION(), BOOST_INTRUSIVE_PP_DECLVAL, _) ), 0 + ) + ) + ) + ); + }; + + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + #endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) + + #endif //BOOST_PP_ITERATION() == 0 + + #if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH() + + #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) + + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN + + template + struct BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl) + ::value + BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), P) > + {}; + + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + + #endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING) + + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + + #endif //#if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH() + +#endif //!BOOST_PP_IS_ITERATING diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp index 9123f3a..ac6ab81 100644 --- a/include/boost/intrusive/detail/hashtable_node.hpp +++ b/include/boost/intrusive/detail/hashtable_node.hpp @@ -16,11 +16,12 @@ #include #include #include -#include +#include #include #include #include -#include //remove-me +//#include //remove-me +#include #include #include #include @@ -84,8 +85,10 @@ struct bucket_traits_impl public: /// @cond - typedef typename boost::pointer_to_other - < typename Slist::pointer, bucket_impl >::type bucket_ptr; + + typedef typename pointer_traits + ::template rebind_pointer + < bucket_impl >::type bucket_ptr; typedef typename Slist::size_type size_type; /// @endcond @@ -93,14 +96,19 @@ struct bucket_traits_impl : buckets_(buckets), buckets_len_(len) {} + bucket_traits_impl(const bucket_traits_impl &x) + : buckets_(x.buckets_), buckets_len_(x.buckets_len_) + {} + + bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x) : buckets_(x.buckets_), buckets_len_(x.buckets_len_) - { x.buckets_ = bucket_ptr(0); x.buckets_len_ = 0; } + { x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; } bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x) { buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; - x.buckets_ = bucket_ptr(0); x.buckets_len_ = 0; return *this; + x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; return *this; } bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x) @@ -108,7 +116,7 @@ struct bucket_traits_impl buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; return *this; } - bucket_ptr bucket_begin() const + const bucket_ptr &bucket_begin() const { return buckets_; } size_type bucket_count() const @@ -124,7 +132,7 @@ class hashtable_iterator : public std::iterator < std::forward_iterator_tag , typename Container::value_type - , typename std::iterator_traits::difference_type + , typename pointer_traits::difference_type , typename detail::add_const_if_c ::type * , typename detail::add_const_if_c @@ -135,16 +143,16 @@ class hashtable_iterator typedef typename Container::siterator siterator; typedef typename Container::const_siterator const_siterator; typedef typename Container::bucket_type bucket_type; - typedef typename boost::pointer_to_other - < typename Container::pointer, const Container>::type const_cont_ptr; + + typedef typename pointer_traits + ::template rebind_pointer + < const Container >::type const_cont_ptr; typedef typename Container::size_type size_type; static typename Container::node_ptr downcast_bucket(typename bucket_type::node_ptr 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)); + return pointer_traits:: + pointer_to(static_cast(*p)); } public: @@ -158,7 +166,7 @@ class hashtable_iterator {} explicit hashtable_iterator(siterator ptr, const Container *cont) - : slist_it_ (ptr), cont_ (cont) + : slist_it_ (ptr), cont_ (cont ? pointer_traits::pointer_to(*cont) : const_cont_ptr() ) {} hashtable_iterator(const hashtable_iterator &other) @@ -192,10 +200,13 @@ class hashtable_iterator { return *this->operator ->(); } pointer operator->() const - { return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node()))); } + { + return boost::intrusive::detail::to_raw_pointer(this->get_real_value_traits()->to_value_ptr + (downcast_bucket(slist_it_.pointed_node()))); + } - const Container *get_container() const - { return detail::boost_intrusive_get_pointer(cont_); } + const const_cont_ptr &get_container() const + { return cont_; } const real_value_traits *get_real_value_traits() const { return &this->get_container()->get_real_value_traits(); } @@ -203,8 +214,8 @@ class hashtable_iterator private: void increment() { - const Container *cont = detail::boost_intrusive_get_pointer(cont_); - bucket_type* buckets = detail::boost_intrusive_get_pointer(cont->bucket_pointer()); + const Container *cont = boost::intrusive::detail::to_raw_pointer(cont_); + bucket_type* buckets = boost::intrusive::detail::to_raw_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 e5df150..df99912 100644 --- a/include/boost/intrusive/detail/list_node.hpp +++ b/include/boost/intrusive/detail/list_node.hpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include namespace boost { namespace intrusive { @@ -29,8 +29,8 @@ namespace intrusive { template struct list_node { - typedef typename boost::pointer_to_other - ::type node_ptr; + typedef typename pointer_traits + :: template rebind_pointer::type node_ptr; node_ptr next_; node_ptr prev_; }; @@ -39,21 +39,21 @@ template struct list_node_traits { typedef list_node node; - typedef typename boost::pointer_to_other - ::type node_ptr; - typedef typename boost::pointer_to_other - ::type const_node_ptr; + typedef typename pointer_traits + :: template rebind_pointer::type node_ptr; + typedef typename pointer_traits + :: template rebind_pointer::type const_node_ptr; - static node_ptr get_previous(const_node_ptr n) + static const node_ptr &get_previous(const const_node_ptr & n) { return n->prev_; } - static void set_previous(node_ptr n, node_ptr prev) + static void set_previous(const node_ptr & n, const node_ptr & prev) { n->prev_ = prev; } - static node_ptr get_next(const_node_ptr n) + static const node_ptr &get_next(const const_node_ptr & n) { return n->next_; } - static void set_next(node_ptr n, node_ptr next) + static void set_next(const node_ptr & n, const node_ptr & next) { n->next_ = next; } }; @@ -74,8 +74,8 @@ class list_iterator typedef typename real_value_traits::node_traits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; - typedef typename boost::pointer_to_other - ::type void_pointer; + typedef typename pointer_traits:: + template rebind_pointer::type void_pointer; static const bool store_container_ptr = detail::store_cont_ptr_on_it::value; @@ -85,10 +85,10 @@ class list_iterator typedef typename detail::if_c::type reference; list_iterator() - : members_ (node_ptr(0), 0) + : members_ (node_ptr(), 0) {} - explicit list_iterator(node_ptr node, const Container *cont_ptr) + explicit list_iterator(const node_ptr & node, const Container *cont_ptr) : members_ (node, cont_ptr) {} @@ -104,8 +104,10 @@ class list_iterator public: list_iterator& operator++() - { - members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + { + node_ptr p = node_traits::get_next(members_.nodeptr_); + members_.nodeptr_ = p; + //members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); return static_cast (*this); } @@ -139,7 +141,7 @@ class list_iterator { return *operator->(); } pointer operator->() const - { return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); } + { return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); } const Container *get_container() const { diff --git a/include/boost/intrusive/detail/memory_util.hpp b/include/boost/intrusive/detail/memory_util.hpp new file mode 100644 index 0000000..72e792a --- /dev/null +++ b/include/boost/intrusive/detail/memory_util.hpp @@ -0,0 +1,250 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Pablo Halpern 2009. 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) +// +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2011-2011. 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_ALLOCATOR_MEMORY_UTIL_HPP +#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +inline T* addressof(T& obj) +{ + return static_cast + (static_cast + (const_cast + (&reinterpret_cast(obj)) + ) + ); +} + +template struct unvoid { typedef T type; }; +template <> struct unvoid { struct type { }; }; +template <> struct unvoid { struct type { }; }; + +template +struct LowPriorityConversion +{ + // Convertible from T with user-defined-conversion rank. + LowPriorityConversion(const T&) { } +}; + +// Infrastructure for providing a default type for T::TNAME if absent. +#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \ + template \ + struct boost_intrusive_default_type_ ## TNAME \ + { \ + template \ + static char test(int, typename X::TNAME*); \ + \ + template \ + static int test(boost::intrusive::detail:: \ + LowPriorityConversion, void*); \ + \ + struct DefaultWrap { typedef DefaultType TNAME; }; \ + \ + static const bool value = (1 == sizeof(test(0, 0))); \ + \ + typedef typename \ + ::boost::intrusive::detail::if_c::type::TNAME type; \ + } \ +// + +#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ + typename INSTANTIATION_NS_PREFIX \ + boost_intrusive_default_type_ ## TNAME::type \ +// + +}}} //namespace boost::intrusive::detail + +#include + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, )) +#include BOOST_PP_ITERATE() + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, )) +#include BOOST_PP_ITERATE() + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, )) +#include BOOST_PP_ITERATE() + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, )) +#include BOOST_PP_ITERATE() + +namespace boost { +namespace intrusive { +namespace detail { + +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(element_type); +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type); + +////////////////////// +//struct first_param +////////////////////// + +template struct first_param +{ typedef void type; }; + +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) + + template