summaryrefslogtreecommitdiff
path: root/boost/intrusive/slist.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/intrusive/slist.hpp')
-rw-r--r--boost/intrusive/slist.hpp206
1 files changed, 93 insertions, 113 deletions
diff --git a/boost/intrusive/slist.hpp b/boost/intrusive/slist.hpp
index 757508149b..dd3a05f2f8 100644
--- a/boost/intrusive/slist.hpp
+++ b/boost/intrusive/slist.hpp
@@ -416,8 +416,7 @@ class slist_impl
void push_front(reference value)
{
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
if(cache_last){
if(this->empty()){
this->set_last_node(to_insert);
@@ -442,8 +441,7 @@ class slist_impl
{
BOOST_STATIC_ASSERT((cache_last));
node_ptr n = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_algorithms::link_after(this->get_last_node(), n);
if(cache_last){
this->set_last_node(n);
@@ -768,6 +766,34 @@ class slist_impl
rollback.release();
}
+ //! <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()(reference)
+ //! and inserts them on *this.
+ //!
+ //! 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.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(slist_impl) src, Cloner cloner, Disposer disposer)
+ {
+ this->clear_and_dispose(disposer);
+ detail::exception_disposer<slist_impl, Disposer>
+ rollback(*this, disposer);
+ iterator prev(this->cbefore_begin());
+ iterator b(src.begin()), e(src.end());
+ for(; b != e; ++b){
+ prev = this->insert_after(prev, *cloner(*b));
+ }
+ rollback.release();
+ }
+
//! <b>Requires</b>: value must be an lvalue and prev_p must point to an element
//! contained by the list or to end().
//!
@@ -784,8 +810,7 @@ class slist_impl
iterator insert_after(const_iterator prev_p, reference value)
{
node_ptr n = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_ptr prev_n(prev_p.pointed_node());
node_algorithms::link_after(prev_n, n);
if(cache_last && (this->get_last_node() == prev_n)){
@@ -815,8 +840,7 @@ class slist_impl
node_ptr prev_n(prev_p.pointed_node());
for (; f != l; ++f, ++count){
const node_ptr n = priv_value_traits().to_node_ptr(*f);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_algorithms::link_after(prev_n, n);
prev_n = n;
}
@@ -1028,6 +1052,15 @@ class slist_impl
/// @cond
+ static iterator s_insert_after(const_iterator const prev_p, reference value)
+ {
+ BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
+ node_ptr const n = value_traits::to_node_ptr(value);
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
+ node_algorithms::link_after(prev_p.pointed_node(), n);
+ return iterator (n, const_value_traits_ptr());
+ }
+
template<class Disposer>
static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer)
{
@@ -1044,6 +1077,23 @@ class slist_impl
return it.unconst();
}
+ template<class Disposer>
+ static iterator s_erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer)
+ {
+ BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
+ node_ptr bfp(before_f.pointed_node()), lp(l.pointed_node());
+ node_ptr fp(node_traits::get_next(bfp));
+ node_algorithms::unlink_after(bfp, lp);
+ while(fp != lp){
+ node_ptr to_erase(fp);
+ fp = node_traits::get_next(fp);
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
+ disposer(value_traits::to_value_ptr(to_erase));
+ }
+ return l.unconst();
+ }
+
static iterator s_erase_after(const_iterator prev)
{ return s_erase_after_and_dispose(prev, detail::null_disposer()); }
@@ -1905,6 +1955,33 @@ class slist_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
}
+
+ friend bool operator==(const slist_impl &x, const slist_impl &y)
+ {
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
+ }
+
+ friend bool operator!=(const slist_impl &x, const slist_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const slist_impl &x, const slist_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const slist_impl &x, const slist_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const slist_impl &x, const slist_impl &y)
+ { return !(y < x); }
+
+ friend bool operator>=(const slist_impl &x, const slist_impl &y)
+ { return !(x < y); }
+
+ friend void swap(slist_impl &x, slist_impl &y)
+ { x.swap(y); }
+
private:
void priv_splice_after(const node_ptr & prev_pos_n, slist_impl &x, const node_ptr & before_f_n, const node_ptr & before_l_n)
{
@@ -2044,111 +2121,6 @@ class slist_impl
}
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator<
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-bool operator==
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{
- typedef slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> slist_type;
- const bool C = slist_type::constant_time_size;
- if(C && x.size() != y.size()){
- return false;
- }
- return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
-}
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator!=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(x == y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator>
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return y < x; }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator<=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(y < x); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator>=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(x < y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline void swap
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
-#else
-( slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ x.swap(y); }
-
//! Helper metafunction to define a \c slist that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
@@ -2241,6 +2213,14 @@ class slist
slist& operator=(BOOST_RV_REF(slist) x)
{ return static_cast<slist &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const slist &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(slist) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static slist &container_from_end_iterator(iterator end_iterator)
{ return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); }