diff options
Diffstat (limited to 'boost/intrusive/list.hpp')
-rw-r--r-- | boost/intrusive/list.hpp | 167 |
1 files changed, 64 insertions, 103 deletions
diff --git a/boost/intrusive/list.hpp b/boost/intrusive/list.hpp index 906b002907..cc6d73bb43 100644 --- a/boost/intrusive/list.hpp +++ b/boost/intrusive/list.hpp @@ -248,8 +248,7 @@ class list_impl void push_back(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)); node_algorithms::link_before(this->get_root_node(), to_insert); this->priv_size_traits().increment(); } @@ -267,8 +266,7 @@ class list_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)); node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert); this->priv_size_traits().increment(); } @@ -770,6 +768,33 @@ class list_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. Basic guarantee. + template <class Cloner, class Disposer> + void clone_from(BOOST_RV_REF(list_impl) src, Cloner cloner, Disposer disposer) + { + this->clear_and_dispose(disposer); + detail::exception_disposer<list_impl, Disposer> + rollback(*this, disposer); + iterator b(src.begin()), e(src.end()); + for(; b != e; ++b){ + this->push_back(*cloner(*b)); + } + rollback.release(); + } + //! <b>Requires</b>: value must be an lvalue and p must be a valid iterator of *this. //! //! <b>Effects</b>: Inserts the value before the position pointed by p. @@ -784,8 +809,7 @@ class list_impl iterator insert(const_iterator p, reference value) { node_ptr to_insert = this->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)); node_algorithms::link_before(p.pointed_node(), to_insert); this->priv_size_traits().increment(); return iterator(to_insert, this->priv_value_traits_ptr()); @@ -1320,6 +1344,32 @@ class list_impl BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count); } + friend bool operator==(const list_impl &x, const list_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 list_impl &x, const list_impl &y) + { return !(x == y); } + + friend bool operator<(const list_impl &x, const list_impl &y) + { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + + friend bool operator>(const list_impl &x, const list_impl &y) + { return y < x; } + + friend bool operator<=(const list_impl &x, const list_impl &y) + { return !(y < x); } + + friend bool operator>=(const list_impl &x, const list_impl &y) + { return !(x < y); } + + friend void swap(list_impl &x, list_impl &y) + { x.swap(y); } + /// @cond private: @@ -1338,103 +1388,6 @@ class list_impl /// @endcond }; -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -template<class T, class ...Options> -#else -template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder> -#endif -inline bool operator< -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y) -#else -(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, 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, bool ConstantTimeSize, typename HeaderHolder> -#endif -bool operator== -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y) -#else -(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) -#endif -{ - typedef list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> list_type; - const bool C = list_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, bool ConstantTimeSize, typename HeaderHolder> -#endif -inline bool operator!= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y) -#else -(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) -#endif -{ return !(x == y); } - -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -template<class T, class ...Options> -#else -template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder> -#endif -inline bool operator> -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y) -#else -(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) -#endif -{ return y < x; } - -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -template<class T, class ...Options> -#else -template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder> -#endif -inline bool operator<= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y) -#else -(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) -#endif -{ return !(y < x); } - -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -template<class T, class ...Options> -#else -template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder> -#endif -inline bool operator>= -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y) -#else -(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) -#endif -{ return !(x < y); } - -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -template<class T, class ...Options> -#else -template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder> -#endif -inline void swap -#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -(list_impl<T, Options...> &x, list_impl<T, Options...> &y) -#else -(list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) -#endif -{ x.swap(y); } //! Helper metafunction to define a \c list that yields to the same type when the //! same options (either explicitly or implicitly) are used. @@ -1518,6 +1471,14 @@ class list list& operator=(BOOST_RV_REF(list) x) { return static_cast<list &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } + template <class Cloner, class Disposer> + void clone_from(const list &src, Cloner cloner, Disposer disposer) + { Base::clone_from(src, cloner, disposer); } + + template <class Cloner, class Disposer> + void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer) + { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); } + static list &container_from_end_iterator(iterator end_iterator) { return static_cast<list &>(Base::container_from_end_iterator(end_iterator)); } |