mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-03 14:34:44 +02:00
Add new clone_from overload to implement move semantics
This commit is contained in:
@@ -945,8 +945,8 @@ class bstree_impl
|
|||||||
detail::exception_disposer<bstree_impl, Disposer>
|
detail::exception_disposer<bstree_impl, Disposer>
|
||||||
rollback(*this, disposer);
|
rollback(*this, disposer);
|
||||||
node_algorithms::clone
|
node_algorithms::clone
|
||||||
(const_node_ptr(src.header_ptr())
|
(src.header_ptr()
|
||||||
,node_ptr(this->header_ptr())
|
,this->header_ptr()
|
||||||
,detail::node_cloner <Cloner, value_traits, AlgoType>(cloner, &this->get_value_traits())
|
,detail::node_cloner <Cloner, value_traits, AlgoType>(cloner, &this->get_value_traits())
|
||||||
,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
|
,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
|
||||||
this->sz_traits().set_size(src.sz_traits().get_size());
|
this->sz_traits().set_size(src.sz_traits().get_size());
|
||||||
@@ -955,6 +955,41 @@ class bstree_impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
|
||||||
|
//! Cloner should yield to nodes equivalent to the original nodes.
|
||||||
|
//!
|
||||||
|
//! <b>Effects</b>: Erases all the elements from *this
|
||||||
|
//! calling Disposer::operator()(pointer), clones all the
|
||||||
|
//! elements from src calling Cloner::operator()(const_reference )
|
||||||
|
//! and inserts them on *this. Copies the predicate from the source container.
|
||||||
|
//!
|
||||||
|
//! If cloner throws, all cloned elements are unlinked and disposed
|
||||||
|
//! calling Disposer::operator()(pointer).
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear to erased plus inserted elements.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
|
||||||
|
//!
|
||||||
|
//! <b>Note</b>: This version can modify the source container, useful to implement
|
||||||
|
//! move semantics.
|
||||||
|
template <class Cloner, class Disposer>
|
||||||
|
void clone_from(bstree_impl &src, Cloner cloner, Disposer disposer)
|
||||||
|
{
|
||||||
|
this->clear_and_dispose(disposer);
|
||||||
|
if(!src.empty()){
|
||||||
|
detail::exception_disposer<bstree_impl, Disposer>
|
||||||
|
rollback(*this, disposer);
|
||||||
|
node_algorithms::clone
|
||||||
|
(src.header_ptr()
|
||||||
|
,this->header_ptr()
|
||||||
|
,detail::node_cloner <Cloner, value_traits, AlgoType, false>(cloner, &this->get_value_traits())
|
||||||
|
,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
|
||||||
|
this->sz_traits().set_size(src.sz_traits().get_size());
|
||||||
|
this->comp() = src.comp();
|
||||||
|
rollback.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! <b>Requires</b>: value must be an lvalue
|
//! <b>Requires</b>: value must be an lvalue
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Inserts value into the container before the upper bound.
|
//! <b>Effects</b>: Inserts value into the container before the upper bound.
|
||||||
|
@@ -1285,7 +1285,7 @@ class bstree_algorithms : public bstree_algorithms_base<NodeTraits>
|
|||||||
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
|
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
|
||||||
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
|
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the
|
||||||
//! number of elements of tree target tree when calling this function.
|
//! number of elements of tree target tree when calling this function.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||||
|
@@ -183,7 +183,7 @@ class ebo_functor_holder_impl<T, false>
|
|||||||
public:
|
public:
|
||||||
ebo_functor_holder_impl()
|
ebo_functor_holder_impl()
|
||||||
{}
|
{}
|
||||||
ebo_functor_holder_impl(const T& t)
|
explicit ebo_functor_holder_impl(const T& t)
|
||||||
: T(t)
|
: T(t)
|
||||||
{}
|
{}
|
||||||
template<class Arg1, class Arg2>
|
template<class Arg1, class Arg2>
|
||||||
@@ -204,7 +204,7 @@ class ebo_functor_holder
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ebo_functor_holder(){}
|
ebo_functor_holder(){}
|
||||||
ebo_functor_holder(const T& t)
|
explicit ebo_functor_holder(const T& t)
|
||||||
: super(t)
|
: super(t)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
|
#include <boost/intrusive/detail/mpl.hpp>
|
||||||
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
||||||
#include <boost/intrusive/detail/algo_type.hpp>
|
#include <boost/intrusive/detail/algo_type.hpp>
|
||||||
#include <boost/intrusive/detail/assert.hpp>
|
#include <boost/intrusive/detail/assert.hpp>
|
||||||
@@ -30,7 +31,7 @@ namespace boost {
|
|||||||
namespace intrusive {
|
namespace intrusive {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class F, class ValueTraits, algo_types AlgoType>
|
template<class F, class ValueTraits, algo_types AlgoType, bool IsConst = true>
|
||||||
struct node_cloner
|
struct node_cloner
|
||||||
//Use public inheritance to avoid MSVC bugs with closures
|
//Use public inheritance to avoid MSVC bugs with closures
|
||||||
: public ebo_functor_holder<F>
|
: public ebo_functor_holder<F>
|
||||||
@@ -50,6 +51,8 @@ struct node_cloner
|
|||||||
typedef typename value_traits::reference reference;
|
typedef typename value_traits::reference reference;
|
||||||
typedef typename value_traits::const_reference const_reference;
|
typedef typename value_traits::const_reference const_reference;
|
||||||
|
|
||||||
|
typedef typename if_c<IsConst, const_reference, reference>::type reference_type;
|
||||||
|
|
||||||
node_cloner(F f, const ValueTraits *traits)
|
node_cloner(F f, const ValueTraits *traits)
|
||||||
: base_t(f), traits_(traits)
|
: base_t(f), traits_(traits)
|
||||||
{}
|
{}
|
||||||
@@ -57,7 +60,7 @@ struct node_cloner
|
|||||||
// tree-based containers use this method, which is proxy-reference friendly
|
// tree-based containers use this method, which is proxy-reference friendly
|
||||||
node_ptr operator()(const node_ptr & p)
|
node_ptr operator()(const node_ptr & p)
|
||||||
{
|
{
|
||||||
const_reference v = *traits_->to_value_ptr(p);
|
reference_type v = *traits_->to_value_ptr(p);
|
||||||
node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
|
node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
|
||||||
//Cloned node must be in default mode if the linking mode requires it
|
//Cloned node must be in default mode if the linking mode requires it
|
||||||
if(safemode_or_autounlink)
|
if(safemode_or_autounlink)
|
||||||
@@ -68,7 +71,7 @@ struct node_cloner
|
|||||||
// hashtables use this method, which is proxy-reference unfriendly
|
// hashtables use this method, which is proxy-reference unfriendly
|
||||||
node_ptr operator()(const node &to_clone)
|
node_ptr operator()(const node &to_clone)
|
||||||
{
|
{
|
||||||
const value_type &v =
|
reference_type v =
|
||||||
*traits_->to_value_ptr
|
*traits_->to_value_ptr
|
||||||
(pointer_traits<const_node_ptr>::pointer_to(to_clone));
|
(pointer_traits<const_node_ptr>::pointer_to(to_clone));
|
||||||
node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
|
node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
|
||||||
|
@@ -213,10 +213,14 @@ class rbtree_impl
|
|||||||
//! @copydoc ::boost::intrusive::bstree::swap
|
//! @copydoc ::boost::intrusive::bstree::swap
|
||||||
void swap(rbtree_impl& other);
|
void swap(rbtree_impl& other);
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::clone_from
|
//! @copydoc ::boost::intrusive::bstree::clone_from(const bstree &src, cloner, Disposer)
|
||||||
template <class Cloner, class Disposer>
|
template <class Cloner, class Disposer>
|
||||||
void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer);
|
void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer);
|
||||||
|
|
||||||
|
//! @copydoc ::boost::intrusive::bstree::clone_from(bstree &src, cloner, Disposer)
|
||||||
|
template <class Cloner, class Disposer>
|
||||||
|
void clone_from(rbtree_impl &src, Cloner cloner, Disposer disposer);
|
||||||
|
|
||||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
|
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
|
||||||
iterator insert_equal(reference value);
|
iterator insert_equal(reference value);
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ struct rbtree_node_cloner
|
|||||||
typedef typename NodeTraits::node_ptr node_ptr;
|
typedef typename NodeTraits::node_ptr node_ptr;
|
||||||
typedef detail::ebo_functor_holder<F> base_t;
|
typedef detail::ebo_functor_holder<F> base_t;
|
||||||
|
|
||||||
rbtree_node_cloner(F f)
|
explicit rbtree_node_cloner(F f)
|
||||||
: base_t(f)
|
: base_t(f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user