From 5645fe2c902044d4e7c28cf89be051d30b84ecbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 26 Aug 2010 21:53:40 +0000 Subject: [PATCH 01/17] Fixes for Boost 1.45 [SVN r65043] --- include/boost/intrusive/rbtree_algorithms.hpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/boost/intrusive/rbtree_algorithms.hpp b/include/boost/intrusive/rbtree_algorithms.hpp index a470a5d..5458e4f 100644 --- a/include/boost/intrusive/rbtree_algorithms.hpp +++ b/include/boost/intrusive/rbtree_algorithms.hpp @@ -57,10 +57,6 @@ #include #include -#if (defined _MSC_VER) && (_MSC_VER >= 1200) -#pragma optimize( "g", off ) -#endif - namespace boost { namespace intrusive { @@ -908,10 +904,6 @@ class rbtree_algorithms } //namespace intrusive } //namespace boost -#if (defined _MSC_VER) && (_MSC_VER >= 1200) -#pragma optimize( "", on ) -#endif - #include #endif //BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP From edd6c98d90f12b315cb2797e6452478b0359dbd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 26 Dec 2010 09:48:36 +0000 Subject: [PATCH 02/17] Fixed wrong count when compare throws [SVN r67450] --- include/boost/intrusive/avltree.hpp | 21 +++++++++++--------- include/boost/intrusive/detail/tree_node.hpp | 2 +- include/boost/intrusive/rbtree.hpp | 12 ++++++----- include/boost/intrusive/sgtree.hpp | 12 +++++------ include/boost/intrusive/splaytree.hpp | 12 ++++++----- include/boost/intrusive/treap.hpp | 21 +++++++++++--------- 6 files changed, 45 insertions(+), 35 deletions(-) diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index 4b6e089..e294d58 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -465,9 +465,10 @@ 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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_equal_upper_bound + iterator ret(node_algorithms::insert_equal_upper_bound (node_ptr(&priv_header()), to_insert, key_node_comp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: value must be an lvalue, and "hint" must be @@ -491,9 +492,10 @@ 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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_equal + iterator ret(node_algorithms::insert_equal (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: Dereferencing iterator must yield an lvalue @@ -698,9 +700,9 @@ 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)); - this->priv_size_traits().increment(); node_algorithms::insert_unique_commit (node_ptr(&priv_header()), to_insert, commit_data); + this->priv_size_traits().increment(); return iterator(to_insert, this); } @@ -723,9 +725,10 @@ 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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_before + iterator ret(node_algorithms::insert_before (node_ptr(&priv_header()), pos.pointed_node(), to_insert), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: value must be an lvalue, and it must be no less @@ -747,8 +750,8 @@ 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)); - this->priv_size_traits().increment(); node_algorithms::push_back(node_ptr(&priv_header()), to_insert); + this->priv_size_traits().increment(); } //! Requires: value must be an lvalue, and it must be no greater @@ -770,8 +773,8 @@ 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)); - this->priv_size_traits().increment(); node_algorithms::push_front(node_ptr(&priv_header()), to_insert); + this->priv_size_traits().increment(); } //! Effects: Erases the element pointed to by pos. diff --git a/include/boost/intrusive/detail/tree_node.hpp b/include/boost/intrusive/detail/tree_node.hpp index f6a678d..00993bc 100644 --- a/include/boost/intrusive/detail/tree_node.hpp +++ b/include/boost/intrusive/detail/tree_node.hpp @@ -96,7 +96,7 @@ class tree_iterator tree_iterator() - : members_ (0, 0) + : members_ (node_ptr(0), (const void *)0) {} explicit tree_iterator(node_ptr nodeptr, const Container *cont_ptr) diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index c8e8ab5..d2b5fe8 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -478,9 +478,10 @@ class rbtree_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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_equal_upper_bound + iterator ret(node_algorithms::insert_equal_upper_bound (node_ptr(&priv_header()), to_insert, key_node_comp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: value must be an lvalue, and "hint" must be @@ -504,9 +505,10 @@ class rbtree_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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_equal + iterator ret(node_algorithms::insert_equal (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: Dereferencing iterator must yield an lvalue @@ -711,9 +713,9 @@ class rbtree_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)); - this->priv_size_traits().increment(); node_algorithms::insert_unique_commit (node_ptr(&priv_header()), to_insert, commit_data); + this->priv_size_traits().increment(); return iterator(to_insert, this); } diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index 5cc361a..2018d0a 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -621,11 +621,11 @@ class sgtree_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)); - this->priv_size_traits().increment(); std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; node_ptr p = node_algorithms::insert_equal_upper_bound (node_ptr(&priv_header()), to_insert, key_node_comp , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size); + this->priv_size_traits().increment(); data_.max_tree_size_ = (size_type)max_tree_size; return iterator(p, this); } @@ -651,11 +651,11 @@ class sgtree_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)); - this->priv_size_traits().increment(); std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; node_ptr p = node_algorithms::insert_equal (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp , (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size); + this->priv_size_traits().increment(); data_.max_tree_size_ = (size_type)max_tree_size; return iterator(p, this); } @@ -862,11 +862,11 @@ class sgtree_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)); - this->priv_size_traits().increment(); std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; node_algorithms::insert_unique_commit ( node_ptr(&priv_header()), to_insert, commit_data , (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size); + this->priv_size_traits().increment(); data_.max_tree_size_ = (size_type)max_tree_size; return iterator(to_insert, this); } @@ -890,11 +890,11 @@ class sgtree_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)); - this->priv_size_traits().increment(); std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; node_ptr p = node_algorithms::insert_before ( node_ptr(&priv_header()), pos.pointed_node(), to_insert , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size); + this->priv_size_traits().increment(); data_.max_tree_size_ = (size_type)max_tree_size; return iterator(p, this); } @@ -918,11 +918,11 @@ class sgtree_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)); - this->priv_size_traits().increment(); std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; node_algorithms::push_back ( node_ptr(&priv_header()), to_insert , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size); + this->priv_size_traits().increment(); data_.max_tree_size_ = (size_type)max_tree_size; } @@ -945,11 +945,11 @@ class sgtree_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)); - this->priv_size_traits().increment(); std::size_t max_tree_size = (std::size_t)data_.max_tree_size_; node_algorithms::push_front ( node_ptr(&priv_header()), to_insert , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size); + this->priv_size_traits().increment(); data_.max_tree_size_ = (size_type)max_tree_size; } diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index 1cb2a2a..244cb0e 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -466,9 +466,10 @@ class splaytree_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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_equal_lower_bound + iterator ret (node_algorithms::insert_equal_lower_bound (node_ptr(&priv_header()), to_insert, key_node_comp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: value must be an lvalue, and "hint" must be @@ -492,9 +493,10 @@ class splaytree_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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_equal + iterator ret(node_algorithms::insert_equal (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: Dereferencing iterator must yield an lvalue @@ -693,9 +695,9 @@ class splaytree_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)); - this->priv_size_traits().increment(); node_algorithms::insert_unique_commit (node_ptr(&priv_header()), to_insert, commit_data); + this->priv_size_traits().increment(); return iterator(to_insert, this); } diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index 86bdd01..9330b35 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -549,9 +549,10 @@ class treap_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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_equal_upper_bound + iterator ret(node_algorithms::insert_equal_upper_bound (node_ptr(&priv_header()), to_insert, key_node_comp, key_node_pcomp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: value must be an lvalue, and "hint" must be @@ -577,9 +578,10 @@ class treap_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)); - this->priv_size_traits().increment(); - return iterator(node_algorithms::insert_equal + iterator ret (node_algorithms::insert_equal (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: Dereferencing iterator must yield an lvalue @@ -801,8 +803,8 @@ class treap_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)); - this->priv_size_traits().increment(); node_algorithms::insert_unique_commit(node_ptr(&priv_header()), to_insert, commit_data); + this->priv_size_traits().increment(); return iterator(to_insert, this); } @@ -825,11 +827,12 @@ class treap_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)); - this->priv_size_traits().increment(); detail::key_nodeptr_comp pcomp(priv_pcomp(), this); - return iterator(node_algorithms::insert_before + iterator ret (node_algorithms::insert_before (node_ptr(&priv_header()), pos.pointed_node(), to_insert, pcomp), this); + this->priv_size_traits().increment(); + return ret; } //! Requires: value must be an lvalue, and it must be no less @@ -851,10 +854,10 @@ class treap_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)); - this->priv_size_traits().increment(); detail::key_nodeptr_comp pcomp(priv_pcomp(), this); node_algorithms::push_back(node_ptr(&priv_header()), to_insert, pcomp); + this->priv_size_traits().increment(); } //! Requires: value must be an lvalue, and it must be no greater @@ -876,10 +879,10 @@ class treap_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)); - this->priv_size_traits().increment(); detail::key_nodeptr_comp pcomp(priv_pcomp(), this); node_algorithms::push_front(node_ptr(&priv_header()), to_insert, pcomp); + this->priv_size_traits().increment(); } //! Effects: Erases the element pointed to by pos. From 13fa2907cdfce01ad1c31f46af63b37a3c6b25ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 26 Dec 2010 09:54:34 +0000 Subject: [PATCH 03/17] Fixed wrong count when compare throws [SVN r67452] --- doc/intrusive.qbk | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index f459c5f..1357b01 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3835,6 +3835,10 @@ all the objects to be inserted in intrusive containers in containers like `std:: * Added `function_hook` option. * Fixed bugs + [@https://svn.boost.org/trac/boost/ticket/2611 #2611], + [@https://svn.boost.org/trac/boost/ticket/3288 #3288], + [@https://svn.boost.org/trac/boost/ticket/3304 #3304], + [@https://svn.boost.org/trac/boost/ticket/3489 #3489], [@https://svn.boost.org/trac/boost/ticket/3668 #3668], [@https://svn.boost.org/trac/boost/ticket/3339 #3688], [@https://svn.boost.org/trac/boost/ticket/3698 #3698], @@ -3843,12 +3847,12 @@ all the objects to be inserted in intrusive containers in containers like `std:: [@https://svn.boost.org/trac/boost/ticket/3729 #3729], [@https://svn.boost.org/trac/boost/ticket/3746 #3746], [@https://svn.boost.org/trac/boost/ticket/3781 #3781], - [@https://svn.boost.org/trac/boost/ticket/3829 #3829], [@https://svn.boost.org/trac/boost/ticket/3840 #3840], + [@https://svn.boost.org/trac/boost/ticket/3849 #3849], [@https://svn.boost.org/trac/boost/ticket/3339 #3339], [@https://svn.boost.org/trac/boost/ticket/3419 #3419], [@https://svn.boost.org/trac/boost/ticket/3431 #3431], - [@https://svn.boost.org/trac/boost/ticket/4021 #4021], + [@https://svn.boost.org/trac/boost/ticket/4021 #4021]. [endsect] From b9dce1daae2c96088cef1b13aa1b73ac175678c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 17 Mar 2011 16:19:41 +0000 Subject: [PATCH 04/17] Ticket #5183 [SVN r70063] --- include/boost/intrusive/avltree.hpp | 2 + include/boost/intrusive/detail/mpl.hpp | 57 +++++++++-------------- include/boost/intrusive/hashtable.hpp | 8 ++-- include/boost/intrusive/options.hpp | 2 +- include/boost/intrusive/rbtree.hpp | 2 + include/boost/intrusive/sgtree.hpp | 2 + include/boost/intrusive/splaytree.hpp | 2 + include/boost/intrusive/treap.hpp | 2 + include/boost/intrusive/unordered_set.hpp | 4 +- 9 files changed, 39 insertions(+), 42 deletions(-) diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index e294d58..51ff0cd 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -1274,6 +1274,8 @@ class avltree_impl node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) , node_ptr(&priv_header()) , get_real_value_traits().to_node_ptr(with_this)); + if(safemode_or_autounlink) + node_algorithms::init(replace_this.pointed_node()); } //! Requires: value must be an lvalue and shall be in a set of diff --git a/include/boost/intrusive/detail/mpl.hpp b/include/boost/intrusive/detail/mpl.hpp index 5f57e37..075381c 100644 --- a/include/boost/intrusive/detail/mpl.hpp +++ b/include/boost/intrusive/detail/mpl.hpp @@ -138,6 +138,10 @@ template struct is_unary_or_binary_function_impl { static const bool value = false; }; +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + template struct is_unary_or_binary_function_impl { static const bool value = true; }; @@ -145,29 +149,17 @@ struct is_unary_or_binary_function_impl template struct is_unary_or_binary_function_impl { static const bool value = true; }; -/* -#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS template struct is_unary_or_binary_function_impl { static const bool value = true; }; -template -struct is_unary_or_binary_function_impl -{ static const bool value = true; }; - -template -struct is_unary_or_binary_function_impl -{ static const bool value = true; }; - template struct is_unary_or_binary_function_impl { static const bool value = true; }; -template -struct is_unary_or_binary_function_impl -{ static const bool value = true; }; - template struct is_unary_or_binary_function_impl { static const bool value = true; }; @@ -175,8 +167,13 @@ struct is_unary_or_binary_function_impl template struct is_unary_or_binary_function_impl { static const bool value = true; }; + #endif -*/ + +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + template struct is_unary_or_binary_function_impl { static const bool value = true; }; @@ -185,24 +182,16 @@ template struct is_unary_or_binary_function_impl { static const bool value = true; }; -#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS template struct is_unary_or_binary_function_impl { static const bool value = true; }; -/* -template -struct is_unary_or_binary_function_impl -{ static const bool value = true; }; template struct is_unary_or_binary_function_impl { static const bool value = true; }; -template -struct is_unary_or_binary_function_impl -{ static const bool value = true; }; - template struct is_unary_or_binary_function_impl { static const bool value = true; }; @@ -210,9 +199,13 @@ struct is_unary_or_binary_function_impl template struct is_unary_or_binary_function_impl { static const bool value = true; }; -*/ + #endif +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + template struct is_unary_or_binary_function_impl { static const bool value = true; }; @@ -220,25 +213,17 @@ struct is_unary_or_binary_function_impl template struct is_unary_or_binary_function_impl { static const bool value = true; }; -/* -#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS template struct is_unary_or_binary_function_impl { static const bool value = true; }; -template -struct is_unary_or_binary_function_impl -{ static const bool value = true; }; - template struct is_unary_or_binary_function_impl { static const bool value = true; }; -template -struct is_unary_or_binary_function_impl -{ static const bool value = true; }; - template struct is_unary_or_binary_function_impl { static const bool value = true; }; @@ -247,7 +232,7 @@ template struct is_unary_or_binary_function_impl { static const bool value = true; }; #endif -*/ + template struct is_unary_or_binary_function_impl { static const bool value = false; }; diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp index 1493eac..30f0472 100644 --- a/include/boost/intrusive/hashtable.hpp +++ b/include/boost/intrusive/hashtable.hpp @@ -37,6 +37,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -123,7 +124,7 @@ struct get_slist_impl < typename NodeTraits::node , boost::intrusive::value_traits , boost::intrusive::constant_time_size - , boost::intrusive::size_type + , boost::intrusive::size_type::difference_type>::type> >::type {}; }; @@ -1677,7 +1678,8 @@ class hashtable_impl //! Throws: If the internal hash function throws. const_iterator iterator_to(const_reference value) const { - return const_iterator(bucket_type::s_iterator_to(priv_value_to_node(const_cast(value))), this); + siterator sit = bucket_type::s_iterator_to(const_cast(this->priv_value_to_node(value))); + return const_iterator(sit, this); } //! Requires: value must be an lvalue and shall be in a unordered_set of @@ -2147,7 +2149,7 @@ class hashtable_impl { const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0]; const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size; - size_type const* bound = std::lower_bound(primes, primes_end, n); + std::size_t const* bound = std::lower_bound(primes, primes_end, n); if(bound == primes_end) --bound; return size_type(*bound); diff --git a/include/boost/intrusive/options.hpp b/include/boost/intrusive/options.hpp index 9731651..4cdeccd 100644 --- a/include/boost/intrusive/options.hpp +++ b/include/boost/intrusive/options.hpp @@ -775,7 +775,7 @@ template struct do_pack > { typedef typename Prev::template pack - >::type> type; + >::type> type; }; diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index d2b5fe8..84937b9 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -1286,6 +1286,8 @@ class rbtree_impl node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) , node_ptr(&priv_header()) , get_real_value_traits().to_node_ptr(with_this)); + if(safemode_or_autounlink) + node_algorithms::init(replace_this.pointed_node()); } //! Requires: value must be an lvalue and shall be in a set of diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index 2018d0a..85689bb 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -1453,6 +1453,8 @@ class sgtree_impl node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) , node_ptr(&priv_header()) , get_real_value_traits().to_node_ptr(with_this)); + if(safemode_or_autounlink) + node_algorithms::init(replace_this.pointed_node()); } //! Requires: value must be an lvalue and shall be in a set of diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index 244cb0e..d378d41 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -1261,6 +1261,8 @@ class splaytree_impl node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) , node_ptr(&priv_header()) , get_real_value_traits().to_node_ptr(with_this)); + if(safemode_or_autounlink) + node_algorithms::init(replace_this.pointed_node()); } //! Requires: value must be an lvalue and shall be in a set of diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index 9330b35..f2952ae 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -1387,6 +1387,8 @@ class treap_impl node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this) , node_ptr(&priv_header()) , get_real_value_traits().to_node_ptr(with_this)); + if(safemode_or_autounlink) + node_algorithms::init(replace_this.pointed_node()); } //! Requires: value must be an lvalue and shall be in a set of diff --git a/include/boost/intrusive/unordered_set.hpp b/include/boost/intrusive/unordered_set.hpp index 2b40f61..4f47b5f 100644 --- a/include/boost/intrusive/unordered_set.hpp +++ b/include/boost/intrusive/unordered_set.hpp @@ -39,7 +39,7 @@ namespace intrusive { //! The container supports the following options: //! \c base_hook<>/member_hook<>/value_traits<>, //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> -//! \c bucket_traits<>, power_2_buckets<> and cache_begin<>. +//! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>. //! //! unordered_set only provides forward iterators but it provides 4 iterator types: //! iterator and const_iterator to navigate through the whole container and @@ -1096,7 +1096,7 @@ class unordered_set //! The container supports the following options: //! \c base_hook<>/member_hook<>/value_traits<>, //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> -//! \c bucket_traits<>, power_2_buckets<> and cache_begin<>. +//! \c bucket_traits<>, \c power_2_buckets<> and \c cache_begin<>. //! //! unordered_multiset only provides forward iterators but it provides 4 iterator types: //! iterator and const_iterator to navigate through the whole container and From 75df697ca85929a25dc9483fca0dd48a2a77c0f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 17 Mar 2011 16:41:49 +0000 Subject: [PATCH 05/17] Ticket #5183 [SVN r70068] --- doc/intrusive.qbk | 14 +++++++++++++ .../vc7ide/_intrusivelib/_intrusivelib.vcproj | 20 +++++++++---------- proj/vc7ide/to-do.txt | 12 +++++++++++ 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index 1357b01..900465b 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3831,6 +3831,20 @@ all the objects to be inserted in intrusive containers in containers like `std:: [section:release_notes Release Notes] +[section:release_notes_boost_1_47_00 Boost 1.47 Release] + +* Fixed bug + [@https://svn.boost.org/trac/boost/ticket/5183 #5183], + +[endsect] + +[section:release_notes_boost_1_46_00 Boost 1.46 Release] + +* Fixed bug + [@https://svn.boost.org/trac/boost/ticket/4980 #4980], + +[endsect] + [section:release_notes_boost_1_45_00 Boost 1.45 Release] * Added `function_hook` option. diff --git a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj index d7f2673..773b3f3 100644 --- a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj +++ b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj @@ -291,18 +291,18 @@ + + + + + + - - - - - - diff --git a/proj/vc7ide/to-do.txt b/proj/vc7ide/to-do.txt index 4a5777f..c5e713d 100644 --- a/proj/vc7ide/to-do.txt +++ b/proj/vc7ide/to-do.txt @@ -15,3 +15,15 @@ -> Document incremental<> option better -> Assure stable order for optimize_multikey and inverse order otherwise -> add an option to unordered containers to get O(1) traversal and begin()/end() even with very low load factors + + +The article explains it quite well: Linear Hashing The cost of hash table expansion is spread out across each hash table insertion operation, as opposed to being incurred all at once. Linear hashing is therefore well suited for interactive applications. + +Linear hashing typically requires power of two length for bucket arrays, but those buckets are not fully used from the beginning, as it is when using non-linear hashing (which typically requires prime bucket length). Although the bucket array hash, say, has 16 buckets, the implementation uses first just one or two, then when after incremental rehashing uses three, etc.. incrementally, until it fills those 16 buckets. Then for a new incremental rehash, it allocates a new bucket array with length 32, but starts using only 17, and continues with incremental hashing. I think Dinkum STL used this incremental rehashing. The key is that in each incremental hashing, not all elements are rehashed, but just elements of a single bucket, distributing hashing impact in all allocations. + +For more information on hashing alternatives see the original standard hashing container proposal (chapter Control of Hash Resizing): + +http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1456.html + +Now, intrusive containers don't allocate memory at all, so incremental rehashing must be trigered by the user using +"incremental_rehash(bool)" (use an additional bucket, that is, incremental rehash) and "incremental_rehash(bucket_traits)" (to update the new bucket array with an array that should be twice/half the size of the previous one). I admit that this is not explained at all with an example, so I will note this issue in my to do list. From 514e48a9d3bedfd05b54d988bd81b2ea12172f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 21 Mar 2011 08:58:28 +0000 Subject: [PATCH 06/17] Added experimental move semantics to containers. Undocumented [SVN r70299] --- include/boost/intrusive/avl_set.hpp | 52 +++++++-- include/boost/intrusive/avltree.hpp | 36 +++++- .../boost/intrusive/detail/hashtable_node.hpp | 22 ++++ include/boost/intrusive/hashtable.hpp | 109 ++++++++++++++---- include/boost/intrusive/list.hpp | 39 +++++-- include/boost/intrusive/rbtree.hpp | 34 +++++- include/boost/intrusive/set.hpp | 52 +++++++-- include/boost/intrusive/sg_set.hpp | 50 ++++++-- include/boost/intrusive/sgtree.hpp | 34 +++++- include/boost/intrusive/slist.hpp | 43 +++++-- include/boost/intrusive/splay_set.hpp | 52 +++++++-- include/boost/intrusive/splaytree.hpp | 33 +++++- include/boost/intrusive/treap.hpp | 37 +++++- include/boost/intrusive/treap_set.hpp | 52 +++++++-- include/boost/intrusive/unordered_set.hpp | 57 ++++++--- 15 files changed, 589 insertions(+), 113 deletions(-) diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index 1c13c62..92baf47 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace boost { @@ -42,12 +43,8 @@ class avl_set_impl /// @cond typedef avltree_impl tree_type; //! This class is - //! non-copyable - avl_set_impl (const avl_set_impl&); - - //! This class is - //! non-assignable - avl_set_impl &operator =(const avl_set_impl&); + //! movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set_impl) typedef tree_type implementation_defined; /// @endcond @@ -113,6 +110,17 @@ class avl_set_impl : tree_(true, b, e, cmp, v_traits) {} + //! Effects: to-do + //! + avl_set_impl(BOOST_RV_REF(avl_set_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + avl_set_impl& operator=(BOOST_RV_REF(avl_set_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the avl_set //! are not deleted (i.e. no destructors are called). //! @@ -1181,6 +1189,7 @@ class avl_set #endif ::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set) public: typedef typename Base::value_compare value_compare; typedef typename Base::value_traits value_traits; @@ -1202,6 +1211,13 @@ class avl_set : Base(b, e, cmp, v_traits) {} + avl_set(BOOST_RV_REF(avl_set) x) + : Base(::boost::move(static_cast(x))) + {} + + avl_set& operator=(BOOST_RV_REF(avl_set) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static avl_set &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } @@ -1238,9 +1254,8 @@ class avl_multiset_impl /// @cond typedef avltree_impl tree_type; - //Non-copyable and non-assignable - avl_multiset_impl (const avl_multiset_impl&); - avl_multiset_impl &operator =(const avl_multiset_impl&); + //Movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset_impl) typedef tree_type implementation_defined; /// @endcond @@ -1305,6 +1320,17 @@ class avl_multiset_impl : tree_(false, b, e, cmp, v_traits) {} + //! Effects: to-do + //! + avl_multiset_impl(BOOST_RV_REF(avl_multiset_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + avl_multiset_impl& operator=(BOOST_RV_REF(avl_multiset_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the avl_multiset //! are not deleted (i.e. no destructors are called). //! @@ -2280,6 +2306,7 @@ class avl_multiset #endif ::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset) public: typedef typename Base::value_compare value_compare; typedef typename Base::value_traits value_traits; @@ -2301,6 +2328,13 @@ class avl_multiset : Base(b, e, cmp, v_traits) {} + avl_multiset(BOOST_RV_REF(avl_multiset) x) + : Base(::boost::move(static_cast(x))) + {} + + avl_multiset& operator=(BOOST_RV_REF(avl_multiset) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static avl_multiset &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index 51ff0cd..5857471 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -32,6 +32,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -122,9 +123,8 @@ class avltree_impl private: typedef detail::size_holder size_traits; - //noncopyable - avltree_impl (const avltree_impl&); - avltree_impl operator =(const avltree_impl&); + //noncopyable, movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree_impl) enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || @@ -159,6 +159,12 @@ class avltree_impl value_compare &priv_comp() { return data_.node_plus_pred_.get(); } + const value_traits &priv_value_traits() const + { return data_; } + + value_traits &priv_value_traits() + { return data_; } + const node &priv_header() const { return data_.node_plus_pred_.header_plus_size_.header_; } @@ -241,6 +247,21 @@ class avltree_impl this->insert_equal(b, e); } + //! Effects: to-do + //! + 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()); + this->priv_size_traits().set_size(size_type(0)); + this->swap(x); + } + + //! Effects: to-do + //! + avltree_impl& operator=(BOOST_RV_REF(avltree_impl) x) + { this->swap(x); return *this; } + //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called), but the nodes according to //! the value_traits template parameter are reinitialized and thus can be reused. @@ -1606,6 +1627,8 @@ class avltree #endif ::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree) + public: typedef typename Base::value_compare value_compare; typedef typename Base::value_traits value_traits; @@ -1628,6 +1651,13 @@ class avltree : Base(unique, b, e, cmp, v_traits) {} + avltree(BOOST_RV_REF(avltree) x) + : Base(::boost::move(static_cast(x))) + {} + + avltree& operator=(BOOST_RV_REF(avltree) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static avltree &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp index 72188b9..9123f3a 100644 --- a/include/boost/intrusive/detail/hashtable_node.hpp +++ b/include/boost/intrusive/detail/hashtable_node.hpp @@ -23,6 +23,9 @@ #include //remove-me #include #include +#include + + namespace boost { namespace intrusive { namespace detail { @@ -76,6 +79,10 @@ struct bucket_impl : public Slist template struct bucket_traits_impl { + private: + BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl) + + public: /// @cond typedef typename boost::pointer_to_other < typename Slist::pointer, bucket_impl >::type bucket_ptr; @@ -86,6 +93,21 @@ struct bucket_traits_impl : buckets_(buckets), buckets_len_(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; } + + 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; + } + + bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x) + { + buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; return *this; + } + bucket_ptr bucket_begin() const { return buckets_; } diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp index 30f0472..2450939 100644 --- a/include/boost/intrusive/hashtable.hpp +++ b/include/boost/intrusive/hashtable.hpp @@ -38,6 +38,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -212,7 +213,7 @@ struct optimize_multikey_is_true template struct bucket_plus_size - : public detail::size_holder + : public detail::size_holder //size_traits < 0 != (Config::bool_flags & hash_bool_flags::constant_time_size_pos) , typename Config::size_type> { @@ -221,15 +222,23 @@ struct bucket_plus_size , typename Config::size_type> size_traits; typedef typename Config::bucket_traits bucket_traits; - bucket_plus_size(const bucket_traits &b_traits) - : bucket_traits_(b_traits) + template + bucket_plus_size(BOOST_FWD_REF(BucketTraits) b_traits) + : bucket_traits_(::boost::forward(b_traits)) {} + + bucket_plus_size & operator =(const bucket_plus_size &x) + { + this->size_traits::operator=(x); + bucket_traits_ = x.bucket_traits_; + return *this; + } bucket_traits bucket_traits_; }; template struct bucket_hash_t - : public detail::ebo_functor_holder + : public detail::ebo_functor_holder //hash { typedef typename Config::hash hasher; typedef detail::size_holder @@ -237,22 +246,26 @@ struct bucket_hash_t , typename Config::size_type> size_traits; typedef typename Config::bucket_traits bucket_traits; - bucket_hash_t(const bucket_traits &b_traits, const hasher & h) - : detail::ebo_functor_holder(h), bucket_plus_size_(b_traits) + template + bucket_hash_t(BOOST_FWD_REF(BucketTraits) b_traits, const hasher & h) + : detail::ebo_functor_holder(h), bucket_plus_size_(::boost::forward(b_traits)) {} bucket_plus_size bucket_plus_size_; }; template -struct bucket_hash_equal_t : public detail::ebo_functor_holder +struct bucket_hash_equal_t + : public detail::ebo_functor_holder { typedef typename Config::equal equal; typedef typename Config::hash hasher; typedef typename Config::bucket_traits bucket_traits; - bucket_hash_equal_t(const bucket_traits &b_traits, const hasher & h, const equal &e) - : detail::ebo_functor_holder(e), bucket_hash(b_traits, h) + template + bucket_hash_equal_t(BOOST_FWD_REF(BucketTraits) b_traits, const hasher & h, const equal &e) + : detail::ebo_functor_holder(e)//equal() + , bucket_hash(::boost::forward(b_traits), h) {} bucket_hash_t bucket_hash; }; @@ -267,8 +280,10 @@ struct bucket_hash_equal_t typedef typename unordered_bucket_ptr_impl ::type bucket_ptr; - bucket_hash_equal_t(const bucket_traits &b_traits, const hasher & h, const equal &e) - : detail::ebo_functor_holder(e), bucket_hash(b_traits, h) + template + bucket_hash_equal_t(BOOST_FWD_REF(BucketTraits) b_traits, const hasher & h, const equal &e) + : detail::ebo_functor_holder(e) //equal() + , bucket_hash(::boost::forward(b_traits), h) {} bucket_hash_t bucket_hash; bucket_ptr cached_begin_; @@ -283,22 +298,25 @@ struct hashtable_data_t : public Config::value_traits typedef typename Config::hash hasher; typedef typename Config::bucket_traits bucket_traits; - hashtable_data_t( const bucket_traits &b_traits, const hasher & h + template + hashtable_data_t( BOOST_FWD_REF(BucketTraits) b_traits, const hasher & h , const equal &e, const value_traits &val_traits) - : Config::value_traits(val_traits), internal_(b_traits, h, e) + : Config::value_traits(val_traits) //value_traits + , internal_(::boost::forward(b_traits), h, e) {} typedef typename detail::usetopt_mask < Config , detail::hash_bool_flags::constant_time_size_pos - | detail::hash_bool_flags::incremental_pos + | detail::hash_bool_flags::incremental_pos >::type masked_config_t; struct internal - : public detail::size_holder + : public detail::size_holder //split_traits < 0 != (Config::bool_flags & hash_bool_flags::incremental_pos) , typename Config::size_type> { - internal(const bucket_traits &b_traits, const hasher & h, const equal &e) - : bucket_hash_equal_(b_traits, h, e) + template + internal(BOOST_FWD_REF(BucketTraits) b_traits, const hasher & h, const equal &e) + : bucket_hash_equal_(::boost::forward(b_traits), h, e) {} bucket_hash_equal_t @@ -707,9 +725,8 @@ class hashtable_impl }; private: - //noncopyable - hashtable_impl (const hashtable_impl&); - hashtable_impl operator =(const hashtable_impl&); + //noncopyable, movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_impl) enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || @@ -791,6 +808,33 @@ class hashtable_impl priv_split_traits().set_size(bucket_size>>1); } + //! Effects: to-do + //! + hashtable_impl(BOOST_RV_REF(hashtable_impl) x) + : data_( ::boost::move(x.priv_bucket_traits()) + , ::boost::move(x.priv_hasher()) + , ::boost::move(x.priv_equal()) + , ::boost::move(x.priv_value_traits()) + ) + { + priv_swap_cache(cache_begin_t(), x); + x.priv_initialize_cache(); + if(constant_time_size){ + this->priv_size_traits().set_size(size_type(0)); + this->priv_size_traits().set_size(x.priv_size_traits().get_size()); + x.priv_size_traits().set_size(size_type(0)); + } + if(incremental){ + this->priv_split_traits().set_size(x.priv_split_traits().get_size()); + x.priv_split_traits().set_size(size_type(0)); + } + } + + //! Effects: to-do + //! + hashtable_impl& operator=(BOOST_RV_REF(hashtable_impl) x) + { this->swap(x); return *this; } + //! Effects: Detaches all elements from this. The objects in the unordered_set //! are not deleted (i.e. no destructors are called). //! @@ -935,14 +979,15 @@ class hashtable_impl swap(this->priv_equal(), other.priv_equal()); swap(this->priv_hasher(), other.priv_hasher()); //These can't throw - swap(this->priv_real_bucket_traits(), other.priv_real_bucket_traits()); + swap(this->priv_bucket_traits(), other.priv_bucket_traits()); + swap(this->priv_value_traits(), other.priv_value_traits()); priv_swap_cache(cache_begin_t(), other); if(constant_time_size){ size_type backup = this->priv_size_traits().get_size(); this->priv_size_traits().set_size(other.priv_size_traits().get_size()); other.priv_size_traits().set_size(backup); } - else if(incremental){ + if(incremental){ size_type backup = this->priv_split_traits().get_size(); this->priv_split_traits().set_size(other.priv_split_traits().get_size()); other.priv_split_traits().set_size(backup); @@ -2201,6 +2246,12 @@ class hashtable_impl key_equal &priv_equal() { return static_cast(this->data_.internal_.bucket_hash_equal_.get()); } + const value_traits &priv_value_traits() const + { return data_; } + + value_traits &priv_value_traits() + { return data_; } + value_type &priv_value_from_slist_node(slist_node_ptr n) { return *this->get_real_value_traits().to_value_ptr(dcast_bucket_ptr(n)); } @@ -2225,6 +2276,12 @@ class hashtable_impl real_bucket_traits &priv_real_bucket_traits() { return this->priv_real_bucket_traits(detail::bool_()); } + const bucket_traits &priv_bucket_traits() const + { return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; } + + bucket_traits &priv_bucket_traits() + { return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; } + const hasher &priv_hasher() const { return static_cast(this->data_.internal_.bucket_hash_equal_.bucket_hash.get()); } @@ -2989,6 +3046,7 @@ class hashtable Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable) public: typedef typename Base::value_traits value_traits; @@ -3010,6 +3068,13 @@ class hashtable , const value_traits &v_traits = value_traits()) : Base(b_traits, hash_func, equal_func, v_traits) {} + + hashtable(BOOST_RV_REF(hashtable) x) + : Base(::boost::move(static_cast(x))) + {} + + hashtable& operator=(BOOST_RV_REF(hashtable) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } }; #endif diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp index ee3e5ba..0df2fe5 100644 --- a/include/boost/intrusive/list.hpp +++ b/include/boost/intrusive/list.hpp @@ -30,7 +30,7 @@ #include #include #include -//iG pending #include +#include namespace boost { namespace intrusive { @@ -114,9 +114,8 @@ class list_impl private: typedef detail::size_holder size_traits; - //Non-copyable and non-moveable - list_impl (const list_impl&); - list_impl &operator =(const list_impl&); + //noncopyable + BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl) enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || @@ -173,10 +172,10 @@ class list_impl real_value_traits &get_real_value_traits(detail::bool_) { return data_.get_value_traits(*this); } - const value_traits &get_value_traits() const + const value_traits &priv_value_traits() const { return data_; } - value_traits &get_value_traits() + value_traits &priv_value_traits() { return data_; } protected: @@ -229,6 +228,21 @@ class list_impl this->insert(this->cend(), b, e); } + //! Effects: to-do + //! + list_impl(BOOST_RV_REF(list_impl) x) + : data_(::boost::move(x.priv_value_traits())) + { + this->priv_size_traits().set_size(size_type(0)); + node_algorithms::init_header(this->get_root_node()); + this->swap(x); + } + + //! Effects: to-do + //! + list_impl& operator=(BOOST_RV_REF(list_impl) x) + { this->swap(x); return *this; } + //! Effects: If it's not a safe-mode or an auto-unlink value_type //! the destructor does nothing //! (ie. no code is generated). Otherwise it detaches all elements from this. @@ -988,8 +1002,8 @@ class list_impl { if(node_traits::get_next(this->get_root_node()) != node_traits::get_previous(this->get_root_node())){ - list_impl carry(this->get_value_traits()); - detail::array_initializer counter(this->get_value_traits()); + list_impl carry(this->priv_value_traits()); + detail::array_initializer counter(this->priv_value_traits()); int fill = 0; while(!this->empty()){ carry.splice(carry.cbegin(), *this, this->cbegin()); @@ -1473,6 +1487,8 @@ class list typedef typename Base::real_value_traits real_value_traits; //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same::value)); + BOOST_MOVABLE_BUT_NOT_COPYABLE(list) + public: typedef typename Base::value_traits value_traits; typedef typename Base::iterator iterator; @@ -1487,6 +1503,13 @@ class list : Base(b, e, v_traits) {} + list(BOOST_RV_REF(list) x) + : Base(::boost::move(static_cast(x))) + {} + + list& operator=(BOOST_RV_REF(list) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static list &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index 84937b9..be06929 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -33,7 +33,7 @@ #include #include #include -//iG pending #include +#include namespace boost { namespace intrusive { @@ -122,8 +122,7 @@ class rbtree_impl typedef detail::size_holder size_traits; //noncopyable - rbtree_impl (const rbtree_impl&); - rbtree_impl operator =(const rbtree_impl&); + BOOST_MOVABLE_BUT_NOT_COPYABLE(rbtree_impl) enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || @@ -158,6 +157,12 @@ class rbtree_impl value_compare &priv_comp() { return data_.node_plus_pred_.get(); } + const value_traits &priv_value_traits() const + { return data_; } + + value_traits &priv_value_traits() + { return data_; } + const node &priv_header() const { return data_.node_plus_pred_.header_plus_size_.header_; } @@ -254,6 +259,21 @@ class rbtree_impl this->insert_equal(b, e); } + //! Effects: to-do + //! + rbtree_impl(BOOST_RV_REF(rbtree_impl) x) + : data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits())) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + this->swap(x); + } + + //! Effects: to-do + //! + rbtree_impl& operator=(BOOST_RV_REF(rbtree_impl) x) + { this->swap(x); return *this; } + //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called), but the nodes according to //! the value_traits template parameter are reinitialized and thus can be reused. @@ -1613,6 +1633,7 @@ class rbtree Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(rbtree) public: typedef typename Base::value_compare value_compare; @@ -1636,6 +1657,13 @@ class rbtree : Base(unique, b, e, cmp, v_traits) {} + rbtree(BOOST_RV_REF(rbtree) x) + : Base(::boost::move(static_cast(x))) + {} + + rbtree& operator=(BOOST_RV_REF(rbtree) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static rbtree &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/set.hpp b/include/boost/intrusive/set.hpp index c85ab08..9b02070 100644 --- a/include/boost/intrusive/set.hpp +++ b/include/boost/intrusive/set.hpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -42,13 +43,7 @@ class set_impl { /// @cond typedef rbtree_impl tree_type; - //! This class is - //! non-copyable - set_impl (const set_impl&); - - //! This class is - //! non-assignable - set_impl &operator =(const set_impl&); + BOOST_MOVABLE_BUT_NOT_COPYABLE(set_impl) typedef tree_type implementation_defined; /// @endcond @@ -122,6 +117,17 @@ class set_impl : tree_(true, b, e, cmp, v_traits) {} + //! Effects: to-do + //! + set_impl(BOOST_RV_REF(set_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + set_impl& operator=(BOOST_RV_REF(set_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called). //! @@ -1190,6 +1196,7 @@ class set #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(set) public: typedef typename Base::value_compare value_compare; typedef typename Base::value_traits value_traits; @@ -1211,6 +1218,13 @@ class set : Base(b, e, cmp, v_traits) {} + set(BOOST_RV_REF(set) x) + : Base(::boost::move(static_cast(x))) + {} + + set& operator=(BOOST_RV_REF(set) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static set &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } @@ -1247,9 +1261,7 @@ class multiset_impl /// @cond typedef rbtree_impl tree_type; - //Non-copyable and non-assignable - multiset_impl (const multiset_impl&); - multiset_impl &operator =(const multiset_impl&); + BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset_impl) typedef tree_type implementation_defined; /// @endcond @@ -1321,6 +1333,17 @@ class multiset_impl : tree_(false, b, e, cmp, v_traits) {} + //! Effects: to-do + //! + multiset_impl(BOOST_RV_REF(multiset_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + multiset_impl& operator=(BOOST_RV_REF(multiset_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called). //! @@ -2307,6 +2330,8 @@ class multiset Options... #endif >::type Base; + + BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset) public: typedef typename Base::value_compare value_compare; @@ -2329,6 +2354,13 @@ class multiset : Base(b, e, cmp, v_traits) {} + multiset(BOOST_RV_REF(multiset) x) + : Base(::boost::move(static_cast(x))) + {} + + multiset& operator=(BOOST_RV_REF(multiset) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static multiset &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/sg_set.hpp b/include/boost/intrusive/sg_set.hpp index 3a7c77a..fb59496 100644 --- a/include/boost/intrusive/sg_set.hpp +++ b/include/boost/intrusive/sg_set.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace boost { @@ -42,12 +43,8 @@ class sg_set_impl /// @cond typedef sgtree_impl tree_type; //! This class is - //! non-copyable - sg_set_impl (const sg_set_impl&); - - //! This class is - //! non-assignable - sg_set_impl &operator =(const sg_set_impl&); + //! movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_set_impl) typedef tree_type implementation_defined; /// @endcond @@ -111,6 +108,17 @@ class sg_set_impl : tree_(true, b, e, cmp, v_traits) {} + //! Effects: to-do + //! + sg_set_impl(BOOST_RV_REF(sg_set_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + sg_set_impl& operator=(BOOST_RV_REF(sg_set_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the sg_set //! are not deleted (i.e. no destructors are called). //! @@ -1218,6 +1226,7 @@ class sg_set Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_set) public: typedef typename Base::value_compare value_compare; @@ -1240,6 +1249,13 @@ class sg_set : Base(b, e, cmp, v_traits) {} + sg_set(BOOST_RV_REF(sg_set) x) + : Base(::boost::move(static_cast(x))) + {} + + sg_set& operator=(BOOST_RV_REF(sg_set) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static sg_set &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } @@ -1277,8 +1293,7 @@ class sg_multiset_impl typedef sgtree_impl tree_type; //Non-copyable and non-assignable - sg_multiset_impl (const sg_multiset_impl&); - sg_multiset_impl &operator =(const sg_multiset_impl&); + BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_multiset_impl) typedef tree_type implementation_defined; /// @endcond @@ -1341,6 +1356,17 @@ class sg_multiset_impl : tree_(false, b, e, cmp, v_traits) {} + //! Effects: to-do + //! + sg_multiset_impl(BOOST_RV_REF(sg_multiset_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + sg_multiset_impl& operator=(BOOST_RV_REF(sg_multiset_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the sg_multiset //! are not deleted (i.e. no destructors are called). //! @@ -2352,6 +2378,7 @@ class sg_multiset Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_multiset) public: typedef typename Base::value_compare value_compare; @@ -2374,6 +2401,13 @@ class sg_multiset : Base(b, e, cmp, v_traits) {} + sg_multiset(BOOST_RV_REF(sg_multiset) x) + : Base(::boost::move(static_cast(x))) + {} + + sg_multiset& operator=(BOOST_RV_REF(sg_multiset) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static sg_multiset &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index 85689bb..7108dbd 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -38,6 +38,7 @@ #include #include #include +#include namespace boost { namespace intrusive { @@ -254,8 +255,7 @@ class sgtree_impl typedef typename alpha_traits::multiply_by_alpha_t multiply_by_alpha_t; //noncopyable - sgtree_impl (const sgtree_impl&); - sgtree_impl operator =(const sgtree_impl&); + BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree_impl) enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || @@ -303,6 +303,12 @@ class sgtree_impl value_compare &priv_comp() { return data_.node_plus_pred_.get(); } + const value_traits &priv_value_traits() const + { return data_; } + + value_traits &priv_value_traits() + { return data_; } + const node &priv_header() const { return data_.node_plus_pred_.header_plus_alpha_.header_; } @@ -395,6 +401,21 @@ class sgtree_impl this->insert_equal(b, e); } + //! Effects: to-do + //! + sgtree_impl(BOOST_RV_REF(sgtree_impl) x) + : data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits())) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + this->swap(x); + } + + //! Effects: to-do + //! + sgtree_impl& operator=(BOOST_RV_REF(sgtree_impl) x) + { this->swap(x); return *this; } + //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called), but the nodes according to //! the value_traits template parameter are reinitialized and thus can be reused. @@ -1838,6 +1859,8 @@ class sgtree #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree) + public: typedef typename Base::value_compare value_compare; typedef typename Base::value_traits value_traits; @@ -1860,6 +1883,13 @@ class sgtree : Base(unique, b, e, cmp, v_traits) {} + sgtree(BOOST_RV_REF(sgtree) x) + : Base(::boost::move(static_cast(x))) + {} + + sgtree& operator=(BOOST_RV_REF(sgtree) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static sgtree &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp index 6aad69e..4eb17df 100644 --- a/include/boost/intrusive/slist.hpp +++ b/include/boost/intrusive/slist.hpp @@ -31,7 +31,7 @@ #include #include //std::size_t #include //std::pair -//iG pending #include +#include namespace boost { namespace intrusive { @@ -148,13 +148,8 @@ class slist_impl private: typedef detail::size_holder size_traits; - //! This class is - //! non-copyable - slist_impl (const slist_impl&); - - //! This class is - //! non-asignable - slist_impl &operator =(const slist_impl&); + //noncopyable + BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl) enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || @@ -252,10 +247,10 @@ class slist_impl real_value_traits &get_real_value_traits(detail::bool_) { return data_.get_value_traits(*this); } - const value_traits &get_value_traits() const + const value_traits &priv_value_traits() const { return data_; } - value_traits &get_value_traits() + value_traits &priv_value_traits() { return data_; } protected: @@ -305,6 +300,21 @@ class slist_impl this->insert_after(this->cbefore_begin(), b, e); } + //! Effects: to-do + //! + slist_impl(BOOST_RV_REF(slist_impl) x) + : data_(::boost::move(x.priv_value_traits())) + { + this->priv_size_traits().set_size(size_type(0)); + node_algorithms::init_header(this->get_root_node()); + this->swap(x); + } + + //! Effects: to-do + //! + slist_impl& operator=(BOOST_RV_REF(slist_impl) x) + { this->swap(x); return *this; } + //! Effects: If it's a safe-mode //! or auto-unlink value, the destructor does nothing //! (ie. no code is generated). Otherwise it detaches all elements from this. @@ -1313,8 +1323,8 @@ class slist_impl if (node_traits::get_next(node_traits::get_next(this->get_root_node())) != this->get_root_node()) { - slist_impl carry(this->get_value_traits()); - detail::array_initializer counter(this->get_value_traits()); + slist_impl carry(this->priv_value_traits()); + detail::array_initializer counter(this->priv_value_traits()); int fill = 0; const_iterator last_inserted; while(!this->empty()){ @@ -2084,6 +2094,8 @@ class slist typedef typename Base::real_value_traits real_value_traits; //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same::value)); + BOOST_MOVABLE_BUT_NOT_COPYABLE(slist) + public: typedef typename Base::value_traits value_traits; typedef typename Base::iterator iterator; @@ -2098,6 +2110,13 @@ class slist : Base(b, e, v_traits) {} + slist(BOOST_RV_REF(slist) x) + : Base(::boost::move(static_cast(x))) + {} + + slist& operator=(BOOST_RV_REF(slist) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static slist &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/splay_set.hpp b/include/boost/intrusive/splay_set.hpp index f899e78..5a21a06 100644 --- a/include/boost/intrusive/splay_set.hpp +++ b/include/boost/intrusive/splay_set.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace boost { @@ -42,12 +43,8 @@ class splay_set_impl /// @cond typedef splaytree_impl tree_type; //! This class is - //! non-copyable - splay_set_impl (const splay_set_impl&); - - //! This class is - //! non-assignable - splay_set_impl &operator =(const splay_set_impl&); + //! movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_set_impl) typedef tree_type implementation_defined; /// @endcond @@ -113,6 +110,17 @@ class splay_set_impl : tree_(true, b, e, cmp, v_traits) {} + //! Effects: to-do + //! + splay_set_impl(BOOST_RV_REF(splay_set_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + splay_set_impl& operator=(BOOST_RV_REF(splay_set_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the splay_set //! are not deleted (i.e. no destructors are called). //! @@ -1202,6 +1210,7 @@ class splay_set Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_set) public: typedef typename Base::value_compare value_compare; @@ -1224,6 +1233,13 @@ class splay_set : Base(b, e, cmp, v_traits) {} + splay_set(BOOST_RV_REF(splay_set) x) + : Base(::boost::move(static_cast(x))) + {} + + splay_set& operator=(BOOST_RV_REF(splay_set) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static splay_set &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } @@ -1260,9 +1276,8 @@ class splay_multiset_impl /// @cond typedef splaytree_impl tree_type; - //Non-copyable and non-assignable - splay_multiset_impl (const splay_multiset_impl&); - splay_multiset_impl &operator =(const splay_multiset_impl&); + //Movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_multiset_impl) typedef tree_type implementation_defined; /// @endcond @@ -1327,6 +1342,17 @@ class splay_multiset_impl : tree_(false, b, e, cmp, v_traits) {} + //! Effects: to-do + //! + splay_multiset_impl(BOOST_RV_REF(splay_multiset_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + splay_multiset_impl& operator=(BOOST_RV_REF(splay_multiset_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called). //! @@ -2324,6 +2350,7 @@ class splay_multiset Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_multiset) public: typedef typename Base::value_compare value_compare; @@ -2346,6 +2373,13 @@ class splay_multiset : Base(b, e, cmp, v_traits) {} + splay_multiset(BOOST_RV_REF(splay_multiset) x) + : Base(::boost::move(static_cast(x))) + {} + + splay_multiset& operator=(BOOST_RV_REF(splay_multiset) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static splay_multiset &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index d378d41..1d04158 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -30,6 +30,7 @@ #include #include #include +#include namespace boost { @@ -122,8 +123,7 @@ class splaytree_impl typedef detail::size_holder size_traits; //noncopyable - splaytree_impl (const splaytree_impl&); - splaytree_impl operator =(const splaytree_impl&); + BOOST_MOVABLE_BUT_NOT_COPYABLE(splaytree_impl) enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || @@ -158,6 +158,12 @@ class splaytree_impl value_compare &priv_comp() { return data_.node_plus_pred_.get(); } + const value_traits &priv_value_traits() const + { return data_; } + + value_traits &priv_value_traits() + { return data_; } + const node &priv_header() const { return data_.node_plus_pred_.header_plus_size_.header_; } @@ -240,6 +246,21 @@ class splaytree_impl this->insert_equal(b, e); } + //! Effects: to-do + //! + splaytree_impl(BOOST_RV_REF(splaytree_impl) x) + : data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits())) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + this->swap(x); + } + + //! Effects: to-do + //! + splaytree_impl& operator=(BOOST_RV_REF(splaytree_impl) x) + { this->swap(x); return *this; } + //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called), but the nodes according to //! the value_traits template parameter are reinitialized and thus can be reused. @@ -1614,6 +1635,7 @@ class splaytree Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(splaytree) public: typedef typename Base::value_compare value_compare; @@ -1637,6 +1659,13 @@ class splaytree : Base(unique, b, e, cmp, v_traits) {} + splaytree(BOOST_RV_REF(splaytree) x) + : Base(::boost::move(static_cast(x))) + {} + + splaytree& operator=(BOOST_RV_REF(splaytree) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static splaytree &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index f2952ae..93d6ca9 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace boost { @@ -126,8 +127,7 @@ class treap_impl typedef detail::size_holder size_traits; //noncopyable - treap_impl (const treap_impl&); - treap_impl operator =(const treap_impl&); + BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_impl) enum { safemode_or_autounlink = (int)real_value_traits::link_mode == (int)auto_unlink || @@ -176,6 +176,12 @@ class treap_impl priority_compare &priv_pcomp() { return data_.node_plus_pred_.header_plus_priority_size_.get(); } + const value_traits &priv_value_traits() const + { return data_; } + + value_traits &priv_value_traits() + { return data_; } + const node &priv_header() const { return data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_.header_; } @@ -224,7 +230,7 @@ class treap_impl //! Throws: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or the copy constructor of the value_compare/priority_compare objects throw. Basic guarantee. - treap_impl( const value_compare &cmp = value_compare() + treap_impl( const value_compare &cmp = value_compare() , const priority_compare &pcmp = priority_compare() , const value_traits &v_traits = value_traits()) : data_(cmp, pcmp, v_traits) @@ -261,6 +267,23 @@ class treap_impl this->insert_equal(b, e); } + //! Effects: to-do + //! + treap_impl(BOOST_RV_REF(treap_impl) x) + : data_( ::boost::move(x.priv_comp()) + , ::boost::move(x.priv_pcomp()) + , ::boost::move(x.priv_value_traits())) + { + node_algorithms::init_header(&priv_header()); + this->priv_size_traits().set_size(size_type(0)); + this->swap(x); + } + + //! Effects: to-do + //! + treap_impl& operator=(BOOST_RV_REF(treap_impl) x) + { this->swap(x); return *this; } + //! Effects: Detaches all elements from this. The objects in the set //! are not deleted (i.e. no destructors are called), but the nodes according to //! the value_traits template parameter are reinitialized and thus can be reused. @@ -1701,6 +1724,7 @@ class treap Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(treap) public: typedef typename Base::value_compare value_compare; @@ -1727,6 +1751,13 @@ class treap : Base(unique, b, e, cmp, pcmp, v_traits) {} + treap(BOOST_RV_REF(treap) x) + : Base(::boost::move(static_cast(x))) + {} + + treap& operator=(BOOST_RV_REF(treap) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static treap &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index ef38a1e..01dfcd8 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace boost { @@ -42,12 +43,8 @@ class treap_set_impl /// @cond typedef treap_impl tree_type; //! This class is - //! non-copyable - treap_set_impl (const treap_set_impl&); - - //! This class is - //! non-assignable - treap_set_impl &operator =(const treap_set_impl&); + //! movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl) typedef tree_type implementation_defined; /// @endcond @@ -116,6 +113,17 @@ class treap_set_impl : tree_(true, b, e, cmp, pcmp, v_traits) {} + //! Effects: to-do + //! + treap_set_impl(BOOST_RV_REF(treap_set_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + treap_set_impl& operator=(BOOST_RV_REF(treap_set_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the treap_set //! are not deleted (i.e. no destructors are called). //! @@ -1294,6 +1302,7 @@ class treap_set Options... #endif >::type Base; + BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set) public: typedef typename Base::value_compare value_compare; @@ -1319,6 +1328,13 @@ class treap_set : Base(b, e, cmp, pcmp, v_traits) {} + treap_set(BOOST_RV_REF(treap_set) x) + : Base(::boost::move(static_cast(x))) + {} + + treap_set& operator=(BOOST_RV_REF(treap_set) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static treap_set &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } @@ -1355,9 +1371,7 @@ class treap_multiset_impl /// @cond typedef treap_impl tree_type; - //Non-copyable and non-assignable - treap_multiset_impl (const treap_multiset_impl&); - treap_multiset_impl &operator =(const treap_multiset_impl&); + BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_multiset_impl) typedef tree_type implementation_defined; /// @endcond @@ -1425,6 +1439,17 @@ class treap_multiset_impl : tree_(false, b, e, cmp, pcmp, v_traits) {} + //! Effects: to-do + //! + treap_multiset_impl(BOOST_RV_REF(treap_multiset_impl) x) + : tree_(::boost::move(x.tree_)) + {} + + //! Effects: to-do + //! + treap_multiset_impl& operator=(BOOST_RV_REF(treap_multiset_impl) x) + { tree_ = ::boost::move(x.tree_); return *this; } + //! Effects: Detaches all elements from this. The objects in the treap_multiset //! are not deleted (i.e. no destructors are called). //! @@ -2499,6 +2524,8 @@ class treap_multiset Options... #endif >::type Base; + //Movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_multiset) public: typedef typename Base::value_compare value_compare; @@ -2524,6 +2551,13 @@ class treap_multiset : Base(b, e, cmp, pcmp, v_traits) {} + treap_multiset(BOOST_RV_REF(treap_multiset) x) + : Base(::boost::move(static_cast(x))) + {} + + treap_multiset& operator=(BOOST_RV_REF(treap_multiset) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } + static treap_multiset &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } diff --git a/include/boost/intrusive/unordered_set.hpp b/include/boost/intrusive/unordered_set.hpp index 4f47b5f..6407fcf 100644 --- a/include/boost/intrusive/unordered_set.hpp +++ b/include/boost/intrusive/unordered_set.hpp @@ -16,8 +16,10 @@ #include #include #include +#include #include + namespace boost { namespace intrusive { @@ -68,12 +70,8 @@ class unordered_set_impl typedef hashtable_impl table_type; //! This class is - //! non-copyable - unordered_set_impl (const unordered_set_impl&); - - //! This class is - //! non-assignable - unordered_set_impl &operator =(const unordered_set_impl&); + //! movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set_impl) typedef table_type implementation_defined; /// @endcond @@ -156,6 +154,17 @@ class unordered_set_impl : table_(b_traits, hash_func, equal_func, v_traits) { table_.insert_unique(b, e); } + //! Effects: to-do + //! + unordered_set_impl(BOOST_RV_REF(unordered_set_impl) x) + : table_(::boost::move(x.table_)) + {} + + //! Effects: to-do + //! + unordered_set_impl& operator=(BOOST_RV_REF(unordered_set_impl) x) + { table_ = ::boost::move(x.table_); return *this; } + //! Effects: Detaches all elements from this. The objects in the unordered_set //! are not deleted (i.e. no destructors are called). //! @@ -1046,6 +1055,7 @@ class unordered_set //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same::value)); + BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_set) public: typedef typename Base::value_traits value_traits; @@ -1073,6 +1083,13 @@ class unordered_set , const value_traits &v_traits = value_traits()) : Base(b, e, b_traits, hash_func, equal_func, v_traits) {} + + unordered_set(BOOST_RV_REF(unordered_set) x) + : Base(::boost::move(static_cast(x))) + {} + + unordered_set& operator=(BOOST_RV_REF(unordered_set) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } }; #endif @@ -1125,13 +1142,8 @@ class unordered_multiset_impl typedef hashtable_impl table_type; /// @endcond - //! This class is - //! non-copyable - unordered_multiset_impl (const unordered_multiset_impl&); - - //! This class is - //! non-assignable - unordered_multiset_impl &operator =(const unordered_multiset_impl&); + //Movable + BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset_impl) typedef table_type implementation_defined; @@ -1213,6 +1225,17 @@ class unordered_multiset_impl : table_(b_traits, hash_func, equal_func, v_traits) { table_.insert_equal(b, e); } + //! Effects: to-do + //! + unordered_multiset_impl(BOOST_RV_REF(unordered_multiset_impl) x) + : table_(::boost::move(x.table_)) + {} + + //! Effects: to-do + //! + unordered_multiset_impl& operator=(BOOST_RV_REF(unordered_multiset_impl) x) + { table_ = ::boost::move(x.table_); return *this; } + //! Effects: Detaches all elements from this. The objects in the unordered_multiset //! are not deleted (i.e. no destructors are called). //! @@ -2045,6 +2068,7 @@ class unordered_multiset >::type Base; //Assert if passed value traits are compatible with the type BOOST_STATIC_ASSERT((detail::is_same::value)); + BOOST_MOVABLE_BUT_NOT_COPYABLE(unordered_multiset) public: typedef typename Base::value_traits value_traits; @@ -2072,6 +2096,13 @@ class unordered_multiset , const value_traits &v_traits = value_traits()) : Base(b, e, b_traits, hash_func, equal_func, v_traits) {} + + unordered_multiset(BOOST_RV_REF(unordered_multiset) x) + : Base(::boost::move(static_cast(x))) + {} + + unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x) + { this->Base::operator=(::boost::move(static_cast(x))); return *this; } }; #endif From 3d0b456316092f1ab5e71d557385dd95934928aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 21 Mar 2011 08:59:25 +0000 Subject: [PATCH 07/17] Added experimental move semantics to containers. Undocumented [SVN r70300] --- test/test_container.hpp | 182 +++++++++++++++++++++++----------------- 1 file changed, 104 insertions(+), 78 deletions(-) diff --git a/test/test_container.hpp b/test/test_container.hpp index c900a6b..262872c 100644 --- a/test/test_container.hpp +++ b/test/test_container.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2007-2009 +// (C) Copyright Ion Gaztanaga 2007-2011 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -15,6 +15,7 @@ #include #include +#include namespace boost { namespace intrusive { @@ -78,55 +79,67 @@ template< class Container, class Data > void test_sequence_container(Container & c, Data & d) { assert( d.size() > 2 ); - - c.clear(); - - BOOST_TEST( c.size() == 0 ); - BOOST_TEST( c.empty() ); - - { - typename Data::iterator i = d.begin(); - c.insert( c.begin(), *i ); - c.insert( c.end(), *(++i) ); + c.clear(); + + BOOST_TEST( c.size() == 0 ); + BOOST_TEST( c.empty() ); + + + { + typename Data::iterator i = d.begin(); + c.insert( c.begin(), *i ); + c.insert( c.end(), *(++i) ); + } + + BOOST_TEST( c.size() == 2 ); + BOOST_TEST( !c.empty() ); + + typename Container::iterator i; + i = c.erase( c.begin() ); + + BOOST_TEST( c.size() == 1 ); + + { + typename Data::iterator i = d.begin(); + ++++i; + c.insert( c.begin(), *(i) ); + } + + i = c.erase( c.begin(), c.end() ); + BOOST_TEST( i == c.end() ); + + BOOST_TEST( c.empty() ); + + c.insert( c.begin(), *d.begin() ); + + BOOST_TEST( c.size() == 1 ); + + BOOST_TEST( c.begin() != c.end() ); + + i = c.erase_and_dispose( c.begin(), detail::null_disposer() ); + BOOST_TEST( i == c.begin() ); + + c.assign(d.begin(), d.end()); + + BOOST_TEST( c.size() == d.size() ); + + c.clear(); + + BOOST_TEST( c.size() == 0 ); + BOOST_TEST( c.empty() ); } - - BOOST_TEST( c.size() == 2 ); - BOOST_TEST( !c.empty() ); - - typename Container::iterator i; - i = c.erase( c.begin() ); - - BOOST_TEST( c.size() == 1 ); - { - typename Data::iterator i = d.begin(); - ++++i; - c.insert( c.begin(), *(i) ); + c.clear(); + c.insert( c.begin(), d.begin(), d.end() ); + Container move_c(::boost::move(c)); + BOOST_TEST( move_c.size() == d.size() ); + BOOST_TEST( c.empty()); + + c = ::boost::move(move_c); + BOOST_TEST( c.size() == d.size() ); + BOOST_TEST( move_c.empty()); } - - i = c.erase( c.begin(), c.end() ); - BOOST_TEST( i == c.end() ); - - BOOST_TEST( c.empty() ); - - c.insert( c.begin(), *d.begin() ); - - BOOST_TEST( c.size() == 1 ); - - BOOST_TEST( c.begin() != c.end() ); - - i = c.erase_and_dispose( c.begin(), detail::null_disposer() ); - BOOST_TEST( i == c.begin() ); - - c.assign(d.begin(), d.end()); - - BOOST_TEST( c.size() == d.size() ); - - c.clear(); - - BOOST_TEST( c.size() == 0 ); - BOOST_TEST( c.empty() ); } template< class Container, class Data > @@ -212,42 +225,55 @@ void test_common_unordered_and_associative_container(Container & c, Data & d, bo template< class Container, class Data > void test_common_unordered_and_associative_container(Container & c, Data & d) { - { typedef typename Container::size_type size_type; - - assert( d.size() > 2 ); - - c.clear(); - c.insert(d.begin(), d.end()); - - for( typename Data::const_iterator di = d.begin(), de = d.end(); - di != de; ++di ) { - BOOST_TEST( c.find(*di) != c.end() ); + assert( d.size() > 2 ); + + c.clear(); + c.insert(d.begin(), d.end()); + + for( typename Data::const_iterator di = d.begin(), de = d.end(); + di != de; ++di ) + { + BOOST_TEST( c.find(*di) != c.end() ); + } + + typename Data::const_iterator db = d.begin(); + typename Data::const_iterator da = db++; + + size_type old_size = c.size(); + + c.erase(*da); + BOOST_TEST( c.size() == old_size-1 ); + //This should erase nothing + size_type second_erase = c.erase_and_dispose( *da, detail::null_disposer() ); + BOOST_TEST( second_erase == 0 ); + + BOOST_TEST( c.count(*da) == 0 ); + BOOST_TEST( c.count(*db) != 0 ); + + BOOST_TEST( c.find(*da) == c.end() ); + BOOST_TEST( c.find(*db) != c.end() ); + + BOOST_TEST( c.equal_range(*db).first != c.end() ); + BOOST_TEST( c.equal_range(*da).first == c.equal_range(*da).second ); } + { + c.clear(); + c.insert( d.begin(), d.end() ); + size_type orig_size = c.size(); + Container move_c(::boost::move(c)); + BOOST_TEST(orig_size == move_c.size()); + BOOST_TEST( c.empty()); + for( typename Data::const_iterator di = d.begin(), de = d.end(); + di != de; ++di ) + { BOOST_TEST( move_c.find(*di) != move_c.end() ); } - typename Data::const_iterator db = d.begin(); - typename Data::const_iterator da = db++; - - size_type old_size = c.size(); - - c.erase(*da); - BOOST_TEST( c.size() == old_size-1 ); - //This should not eras anyone - size_type second_erase = c.erase_and_dispose( *da, detail::null_disposer() ); - BOOST_TEST( second_erase == 0 ); - - BOOST_TEST( c.count(*da) == 0 ); - BOOST_TEST( c.count(*db) != 0 ); - - BOOST_TEST( c.find(*da) == c.end() ); - BOOST_TEST( c.find(*db) != c.end() ); - - BOOST_TEST( c.equal_range(*db).first != c.end() ); - - c.clear(); - - BOOST_TEST( c.equal_range(*da).first == c.end() ); + c = ::boost::move(move_c); + for( typename Data::const_iterator di = d.begin(), de = d.end(); + di != de; ++di ) + { BOOST_TEST( c.find(*di) != c.end() ); } + BOOST_TEST( move_c.empty()); } typedef detail::bool_::value> enabler; test_common_unordered_and_associative_container(c, d, enabler()); From 7b1f0e0e530b0f077874123b66938b83d798895c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 28 Mar 2011 08:50:35 +0000 Subject: [PATCH 08/17] Fixes when using pointers as key_type [SVN r70659] --- include/boost/intrusive/detail/utilities.hpp | 39 ++++++++++---------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index 064ff6e..a03bf36 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -207,32 +207,33 @@ struct key_nodeptr_comp : private detail::ebo_functor_holder { typedef typename Container::real_value_traits real_value_traits; + typedef typename Container::value_type value_type; typedef typename real_value_traits::node_ptr node_ptr; typedef typename real_value_traits::const_node_ptr const_node_ptr; typedef detail::ebo_functor_holder base_t; key_nodeptr_comp(KeyValueCompare kcomp, const Container *cont) : base_t(kcomp), cont_(cont) {} - - template - bool operator()( const_node_ptr node, const KeyType &key - , typename enable_if_c - ::value>::type * = 0) const - { return base_t::get()(*cont_->get_real_value_traits().to_value_ptr(node), key); } - - template - bool operator()(const KeyType &key, const_node_ptr node - , typename enable_if_c - ::value>::type * = 0) const - { return base_t::get()(key, *cont_->get_real_value_traits().to_value_ptr(node)); } - - bool operator()(const_node_ptr node1, const_node_ptr node2) const + + template + struct is_node_ptr { - return base_t::get() - ( *cont_->get_real_value_traits().to_value_ptr(node1) - , *cont_->get_real_value_traits().to_value_ptr(node2) - ); - } + static const bool value = is_same::value || is_same::value; + }; + + template + typename enable_if_c::value, const value_type &>::type + key_forward(const T &node) const + { return *cont_->get_real_value_traits().to_value_ptr(node); } + + template + typename enable_if_c::value, const T &>::type + key_forward(const T &key) const + { return key;} + + template + bool operator()(const KeyType &key1, const KeyType2 &key2) const + { return base_t::get()(this->key_forward(key1), this->key_forward(key2)); } const Container *cont_; }; From 85e5b6bc3405aa6dafe4a7c39f1857c7c8f0bcf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Fri, 1 Apr 2011 22:04:17 +0000 Subject: [PATCH 09/17] Fixes for Boost 1.47 [SVN r70839] --- doc/intrusive.qbk | 5 ++++- example/doc_offset_ptr.cpp | 10 ++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index 900465b..166b39d 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3833,8 +3833,11 @@ all the objects to be inserted in intrusive containers in containers like `std:: [section:release_notes_boost_1_47_00 Boost 1.47 Release] -* Fixed bug +* Fixed bugs + [@https://svn.boost.org/trac/boost/ticket/4797 #4797], + [@https://svn.boost.org/trac/boost/ticket/5165 #5165], [@https://svn.boost.org/trac/boost/ticket/5183 #5183], + [@https://svn.boost.org/trac/boost/ticket/5191 #5191]. [endsect] diff --git a/example/doc_offset_ptr.cpp b/example/doc_offset_ptr.cpp index 064ee6e..7fb2414 100644 --- a/example/doc_offset_ptr.cpp +++ b/example/doc_offset_ptr.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2006-2009 +// (C) Copyright Ion Gaztanaga 2006-2011 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -51,7 +51,7 @@ class shared_memory_data #include //Definition of the shared memory friendly intrusive list -typedef ip::list shm_list_t; +typedef list intrusive_list_t; int main() { @@ -80,12 +80,14 @@ int main() for(int i = 0; i < MaxElem; ++i) (*pshm_vect)[i].set(i); //Now create the shared memory intrusive list - shm_list_t *plist = shm.construct(ip::anonymous_instance)(); + intrusive_list_t *plist = shm.construct(ip::anonymous_instance)(); + + //Insert objects stored in shared memory vector in the intrusive list plist->insert(plist->end(), pshm_vect->begin(), pshm_vect->end()); //Check all the inserted nodes int checker = 0; - for( shm_list_t::const_iterator it = plist->begin(), itend(plist->end()) + for( intrusive_list_t::const_iterator it = plist->begin(), itend(plist->end()) ; it != itend; ++it, ++checker){ if(it->get() != checker) return false; } From d56bd7b192d2d173598fbbde91118c2add6d999d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 30 Aug 2011 12:23:34 +0000 Subject: [PATCH 10/17] Documentation fixes, added AutoIndex indexes [SVN r74154] --- doc/Jamfile.v2 | 35 ++++++++++++++++++- doc/html/boostbook.css | 1 - doc/html/reference.css | 1 - doc/index.idx | 1 + doc/intrusive.qbk | 14 +++++++- .../vc7ide/_intrusivelib/_intrusivelib.vcproj | 34 +++++++++--------- 6 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 doc/index.idx diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index f00fe39..8b294de 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -7,6 +7,7 @@ # # See http://www.boost.org/libs/intrusive for documentation. +using auto-index ; import doxygen ; import quickbook ; @@ -44,7 +45,10 @@ doxygen autodoc "treap_impl=treap"" ; -xml intrusive : intrusive.qbk ; +xml intrusive : intrusive.qbk + : + ../../../tools/auto_index/include + ; boostbook standalone : @@ -55,4 +59,33 @@ boostbook standalone generate.section.toc.level=3 chunk.first.sections=1 autodoc + + # Build requirements go here: + + # on (or off) one turns on (or off) indexing: + on + + # Turns on (or off) auto-index-verbose for diagnostic info. + # This is highly recommended until you have got all the many details correct! + on + + # Choose the indexing method (separately for html and PDF) - see manual. + # Choose indexing method for PDFs: + pdf:off + + # Choose indexing method for html: + html:on + + # Set the name of the script file to use (index.idx is popular): + index.idx + # Commands in the script file should all use RELATIVE PATHS + # otherwise the script will not be portable to other machines. + # Relative paths are normally taken as relative to the location + # of the script file, but we can add a prefix to all + # those relative paths using the feature. + # The path specified by may be either relative or + # absolute, for example the following will get us up to the boost root + # directory for most Boost libraries: + "../../.." + ; diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css index e816cce..2146334 100644 --- a/doc/html/boostbook.css +++ b/doc/html/boostbook.css @@ -1,6 +1,5 @@ /*============================================================================= Copyright (c) 2004 Joel de Guzman - http://spirit.sourceforge.net/ Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/doc/html/reference.css b/doc/html/reference.css index 956d7da..1bf6b68 100644 --- a/doc/html/reference.css +++ b/doc/html/reference.css @@ -1,6 +1,5 @@ /*============================================================================= Copyright (c) 2004 Joel de Guzman - http://spirit.sourceforge.net/ Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/doc/index.idx b/doc/index.idx new file mode 100644 index 0000000..e167a46 --- /dev/null +++ b/doc/index.idx @@ -0,0 +1 @@ +!scan-path "boost/intrusive" ".*.hpp" false diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index 166b39d..7ab053a 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3831,7 +3831,7 @@ all the objects to be inserted in intrusive containers in containers like `std:: [section:release_notes Release Notes] -[section:release_notes_boost_1_47_00 Boost 1.47 Release] +[section:release_notes_boost_1_48_00 Boost 1.48 Release] * Fixed bugs [@https://svn.boost.org/trac/boost/ticket/4797 #4797], @@ -3995,4 +3995,16 @@ helpful discussions. [endsect] +[include auto_index_helpers.qbk] + +[section:index Indexes] + +[named_index class_name Class Index] +[named_index typedef_name Typedef Index] +[named_index function_name Function Index] +[named_index macro_name Macro Index] +[/index] + +[endsect] + [xinclude autodoc.xml] \ No newline at end of file diff --git a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj index 773b3f3..f24fe52 100644 --- a/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj +++ b/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj @@ -93,14 +93,6 @@ - - - - - - - - - - + + @@ -465,6 +450,19 @@ RelativePath="..\..\..\perf\perf_list.cpp"> + + + + + + + + From f562f4c04f634c3a78808945f1f44181ad995d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 16 Oct 2011 17:28:44 +0000 Subject: [PATCH 11/17] Fixed bug in renamed detail namespace [SVN r74980] --- example/doc_offset_ptr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/doc_offset_ptr.cpp b/example/doc_offset_ptr.cpp index 7fb2414..feabead 100644 --- a/example/doc_offset_ptr.cpp +++ b/example/doc_offset_ptr.cpp @@ -19,7 +19,7 @@ const char *get_shared_memory_name() { std::stringstream s; - s << "process_" << boost::interprocess::detail::get_current_process_id(); + s << "process_" << boost::interprocess::ipcdetail::get_current_process_id(); static std::string str = s.str(); return str.c_str(); } From 8a53a5af2753a6fb15e200b611090f5d8cdfcab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 22 Dec 2011 20:08:24 +0000 Subject: [PATCH 12/17] Introducing allocator_traits and pointer_traits changes into several libraries. [SVN r76106] --- include/boost/intrusive/any_hook.hpp | 10 +- include/boost/intrusive/avltree.hpp | 118 +++--- .../boost/intrusive/avltree_algorithms.hpp | 104 ++--- .../intrusive/circular_list_algorithms.hpp | 56 +-- .../intrusive/circular_slist_algorithms.hpp | 40 +- .../intrusive/derivation_value_traits.hpp | 10 +- .../detail/any_node_and_algorithms.hpp | 145 ++++--- .../boost/intrusive/detail/avltree_node.hpp | 68 ++-- .../detail/common_slist_algorithms.hpp | 24 +- .../intrusive/detail/function_detector.hpp | 1 + .../boost/intrusive/detail/generic_hook.hpp | 22 +- .../has_member_function_callable_with.hpp | 334 ++++++++++++++++ .../boost/intrusive/detail/hashtable_node.hpp | 51 ++- include/boost/intrusive/detail/list_node.hpp | 38 +- .../boost/intrusive/detail/memory_util.hpp | 250 ++++++++++++ .../intrusive/detail/pointer_to_other.hpp | 65 ---- .../boost/intrusive/detail/preprocessor.hpp | 52 +++ .../boost/intrusive/detail/rbtree_node.hpp | 62 +-- include/boost/intrusive/detail/slist_node.hpp | 28 +- .../intrusive/detail/tree_algorithms.hpp | 230 +++++------ include/boost/intrusive/detail/tree_node.hpp | 38 +- include/boost/intrusive/detail/utilities.hpp | 286 ++++++++++---- include/boost/intrusive/detail/workaround.hpp | 18 +- include/boost/intrusive/hashtable.hpp | 356 +++++++++++------- .../intrusive/linear_slist_algorithms.hpp | 46 +-- include/boost/intrusive/list.hpp | 28 +- .../boost/intrusive/member_value_traits.hpp | 31 +- include/boost/intrusive/pointer_traits.hpp | 265 +++++++++++++ include/boost/intrusive/rbtree.hpp | 105 +++--- include/boost/intrusive/rbtree_algorithms.hpp | 107 +++--- include/boost/intrusive/sgtree.hpp | 107 +++--- include/boost/intrusive/sgtree_algorithms.hpp | 89 +++-- include/boost/intrusive/slist.hpp | 55 ++- include/boost/intrusive/splaytree.hpp | 108 +++--- .../boost/intrusive/splaytree_algorithms.hpp | 147 ++++---- include/boost/intrusive/treap.hpp | 118 +++--- include/boost/intrusive/treap_algorithms.hpp | 99 ++--- .../boost/intrusive/trivial_value_traits.hpp | 11 +- .../boost/intrusive/unordered_set_hook.hpp | 59 +-- 39 files changed, 2448 insertions(+), 1333 deletions(-) create mode 100644 include/boost/intrusive/detail/has_member_function_callable_with.hpp create mode 100644 include/boost/intrusive/detail/memory_util.hpp delete mode 100644 include/boost/intrusive/detail/pointer_to_other.hpp create mode 100644 include/boost/intrusive/detail/preprocessor.hpp create mode 100644 include/boost/intrusive/pointer_traits.hpp 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..25afacf 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 //! @@ -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