diff options
Diffstat (limited to 'boost/intrusive/slist.hpp')
-rw-r--r-- | boost/intrusive/slist.hpp | 206 |
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)); } |