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] 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