Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/intrusive/list.hpp @ 101:c530137014c0
Update Boost headers (1.58.0)
author | Chris Cannam |
---|---|
date | Mon, 07 Sep 2015 11:12:49 +0100 |
parents | 2665513ce2d3 |
children |
line wrap: on
line diff
--- a/DEPENDENCIES/generic/include/boost/intrusive/list.hpp Fri Sep 04 12:01:02 2015 +0100 +++ b/DEPENDENCIES/generic/include/boost/intrusive/list.hpp Mon Sep 07 11:12:49 2015 +0100 @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. -// (C) Copyright Ion Gaztanaga 2006-2013 +// (C) Copyright Ion Gaztanaga 2006-2014 // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -15,34 +15,55 @@ #define BOOST_INTRUSIVE_LIST_HPP #include <boost/intrusive/detail/config_begin.hpp> +#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/detail/assert.hpp> -#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/list_hook.hpp> #include <boost/intrusive/circular_list_algorithms.hpp> #include <boost/intrusive/pointer_traits.hpp> -#include <boost/intrusive/detail/clear_on_destructor_base.hpp> #include <boost/intrusive/detail/mpl.hpp> #include <boost/intrusive/link_mode.hpp> +#include <boost/intrusive/detail/get_value_traits.hpp> +#include <boost/intrusive/detail/is_stateful_value_traits.hpp> +#include <boost/intrusive/detail/default_header_holder.hpp> +#include <boost/intrusive/detail/reverse_iterator.hpp> +#include <boost/intrusive/detail/uncast.hpp> +#include <boost/intrusive/detail/list_iterator.hpp> +#include <boost/intrusive/detail/array_initializer.hpp> +#include <boost/intrusive/detail/exception_disposer.hpp> +#include <boost/intrusive/detail/equal_to_value.hpp> +#include <boost/intrusive/detail/key_nodeptr_comp.hpp> +#include <boost/intrusive/detail/simple_disposers.hpp> +#include <boost/intrusive/detail/size_holder.hpp> +#include <boost/intrusive/detail/algorithm.hpp> + +#include <boost/move/utility_core.hpp> #include <boost/static_assert.hpp> -#include <boost/intrusive/options.hpp> -#include <boost/intrusive/pointer_traits.hpp> -#include <boost/intrusive/detail/utilities.hpp> -#include <iterator> -#include <algorithm> -#include <functional> -#include <cstddef> -#include <boost/move/move.hpp> + +#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//std::less +#include <cstddef> //std::size_t, etc. + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif namespace boost { namespace intrusive { /// @cond +struct default_list_hook_applier +{ template <class T> struct apply{ typedef typename T::default_list_hook type; }; }; + +template<> +struct is_default_hook_tag<default_list_hook_applier> +{ static const bool value = true; }; + struct list_defaults { - typedef detail::default_list_hook proto_value_traits; + typedef default_list_hook_applier proto_value_traits; static const bool constant_time_size = true; typedef std::size_t size_type; + typedef void header_holder_type; }; /// @endcond @@ -60,42 +81,36 @@ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template<class T, class ...Options> #else -template <class ValueTraits, class SizeType, bool ConstantTimeSize> +template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder> #endif class list_impl - : private detail::clear_on_destructor_base - < list_impl<ValueTraits, SizeType, ConstantTimeSize> - , is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value - > { - template<class C, bool> friend class detail::clear_on_destructor_base; //Public typedefs public: - typedef ValueTraits value_traits; - /// @cond - static const bool external_value_traits = - detail::external_value_traits_bool_is_true<value_traits>::value; - typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits; - /// @endcond - typedef typename real_value_traits::pointer pointer; - typedef typename real_value_traits::const_pointer const_pointer; + typedef ValueTraits value_traits; + typedef typename value_traits::pointer pointer; + typedef typename value_traits::const_pointer const_pointer; typedef typename pointer_traits<pointer>::element_type value_type; typedef typename pointer_traits<pointer>::reference reference; typedef typename pointer_traits<const_pointer>::reference const_reference; typedef typename pointer_traits<pointer>::difference_type difference_type; typedef SizeType size_type; - typedef list_iterator<real_value_traits, false> iterator; - typedef list_iterator<real_value_traits, true> const_iterator; - typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator; - typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator; - typedef typename real_value_traits::node_traits node_traits; + typedef list_iterator<value_traits, false> iterator; + typedef list_iterator<value_traits, true> const_iterator; + typedef boost::intrusive::reverse_iterator<iterator> reverse_iterator; + typedef boost::intrusive::reverse_iterator<const_iterator> const_reverse_iterator; + typedef typename value_traits::node_traits node_traits; typedef typename node_traits::node node; typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef circular_list_algorithms<node_traits> node_algorithms; + typedef typename detail::get_header_holder_type + < value_traits, HeaderHolder >::type header_holder_type; static const bool constant_time_size = ConstantTimeSize; - static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value; + static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value; + static const bool has_container_from_iterator = + detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value; /// @cond @@ -105,22 +120,22 @@ //noncopyable BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl) - static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value; + static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value; //Constant-time size is incompatible with auto-unlink hooks! BOOST_STATIC_ASSERT(!(constant_time_size && - ((int)real_value_traits::link_mode == (int)auto_unlink) + ((int)value_traits::link_mode == (int)auto_unlink) )); node_ptr get_root_node() - { return pointer_traits<node_ptr>::pointer_to(data_.root_plus_size_.root_); } + { return data_.root_plus_size_.m_header.get_node(); } const_node_ptr get_root_node() const - { return pointer_traits<const_node_ptr>::pointer_to(data_.root_plus_size_.root_); } + { return data_.root_plus_size_.m_header.get_node(); } struct root_plus_size : public size_traits { - node root_; + header_holder_type m_header; }; struct data_t : public value_traits @@ -139,54 +154,27 @@ const size_traits &priv_size_traits() const { return data_.root_plus_size_; } - const real_value_traits &get_real_value_traits(detail::bool_<false>) const - { return data_; } - - const real_value_traits &get_real_value_traits(detail::bool_<true>) const - { return data_.get_value_traits(*this); } - - real_value_traits &get_real_value_traits(detail::bool_<false>) - { return data_; } - - real_value_traits &get_real_value_traits(detail::bool_<true>) - { return data_.get_value_traits(*this); } - const value_traits &priv_value_traits() const { return data_; } value_traits &priv_value_traits() { return data_; } - protected: - node &prot_root_node() - { return data_.root_plus_size_.root_; } + typedef typename boost::intrusive::value_traits_pointers + <ValueTraits>::const_value_traits_ptr const_value_traits_ptr; - node const &prot_root_node() const - { return data_.root_plus_size_.root_; } - - void prot_set_size(size_type s) - { data_.root_plus_size_.set_size(s); } + const_value_traits_ptr priv_value_traits_ptr() const + { return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); } /// @endcond public: - const real_value_traits &get_real_value_traits() const - { return this->get_real_value_traits(detail::bool_<external_value_traits>()); } - - real_value_traits &get_real_value_traits() - { return this->get_real_value_traits(detail::bool_<external_value_traits>()); } - - typedef typename pointer_traits<node_ptr>::template rebind_pointer<real_value_traits const>::type const_real_value_traits_ptr; - - const_real_value_traits_ptr real_value_traits_ptr() const - { return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); } - //! <b>Effects</b>: constructs an empty list. //! //! <b>Complexity</b>: Constant //! - //! <b>Throws</b>: If real_value_traits::node_traits::node + //! <b>Throws</b>: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). explicit list_impl(const value_traits &v_traits = value_traits()) : data_(v_traits) @@ -199,16 +187,18 @@ //! //! <b>Effects</b>: Constructs a list equal to the range [first,last). //! - //! <b>Complexity</b>: Linear in std::distance(b, e). No copy constructors are called. + //! <b>Complexity</b>: Linear in distance(b, e). No copy constructors are called. //! - //! <b>Throws</b>: If real_value_traits::node_traits::node + //! <b>Throws</b>: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks). template<class Iterator> list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) : data_(v_traits) { + //nothrow, no need to rollback to release elements on exception this->priv_size_traits().set_size(size_type(0)); node_algorithms::init_header(this->get_root_node()); + //nothrow, no need to rollback to release elements on exception this->insert(this->cend(), b, e); } @@ -219,6 +209,7 @@ { this->priv_size_traits().set_size(size_type(0)); node_algorithms::init_header(this->get_root_node()); + //nothrow, no need to rollback to release elements on exception this->swap(x); } @@ -227,7 +218,6 @@ list_impl& operator=(BOOST_RV_REF(list_impl) x) { this->swap(x); return *this; } - #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! <b>Effects</b>: 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. @@ -238,8 +228,12 @@ //! <b>Complexity</b>: Linear to the number of elements in the list, if //! it's a safe-mode or auto-unlink value . Otherwise constant. ~list_impl() - {} - #endif + { + if(is_safe_autounlink<ValueTraits::link_mode>::value){ + this->clear(); + node_algorithms::init(this->get_root_node()); + } + } //! <b>Requires</b>: value must be an lvalue. //! @@ -253,7 +247,7 @@ //! <b>Note</b>: Does not affect the validity of iterators and references. void push_back(reference value) { - node_ptr to_insert = get_real_value_traits().to_node_ptr(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)); node_algorithms::link_before(this->get_root_node(), to_insert); @@ -272,7 +266,7 @@ //! <b>Note</b>: Does not affect the validity of iterators and references. void push_front(reference value) { - node_ptr to_insert = get_real_value_traits().to_node_ptr(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)); node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert); @@ -309,7 +303,7 @@ this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); } //! <b>Effects</b>: Erases the first element of the list. @@ -342,7 +336,7 @@ this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); } //! <b>Effects</b>: Returns a reference to the first element of the list. @@ -351,7 +345,7 @@ //! //! <b>Complexity</b>: Constant. reference front() - { return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } + { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! <b>Effects</b>: Returns a const_reference to the first element of the list. //! @@ -359,7 +353,7 @@ //! //! <b>Complexity</b>: Constant. const_reference front() const - { return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } + { return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } //! <b>Effects</b>: Returns a reference to the last element of the list. //! @@ -367,7 +361,7 @@ //! //! <b>Complexity</b>: Constant. reference back() - { return *get_real_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); } + { return *priv_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); } //! <b>Effects</b>: Returns a const_reference to the last element of the list. //! @@ -375,7 +369,7 @@ //! //! <b>Complexity</b>: Constant. const_reference back() const - { return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); } + { return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); } //! <b>Effects</b>: Returns an iterator to the first element contained in the list. //! @@ -383,7 +377,7 @@ //! //! <b>Complexity</b>: Constant. iterator begin() - { return iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); } + { return iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. //! @@ -399,7 +393,7 @@ //! //! <b>Complexity</b>: Constant. const_iterator cbegin() const - { return const_iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); } + { return const_iterator(node_traits::get_next(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns an iterator to the end of the list. //! @@ -407,7 +401,7 @@ //! //! <b>Complexity</b>: Constant. iterator end() - { return iterator(this->get_root_node(), real_value_traits_ptr()); } + { return iterator(this->get_root_node(), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a const_iterator to the end of the list. //! @@ -423,7 +417,7 @@ //! //! <b>Complexity</b>: Constant. const_iterator cend() const - { return const_iterator(detail::uncast(this->get_root_node()), real_value_traits_ptr()); } + { return const_iterator(detail::uncast(this->get_root_node()), this->priv_value_traits_ptr()); } //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning //! of the reversed list. @@ -610,7 +604,7 @@ } //! <b>Requires</b>: b and e must be valid iterators to elements in *this. - //! n must be std::distance(b, e). + //! n must be distance(b, e). //! //! <b>Effects</b>: Erases the element range pointed by b and e //! No destructors are called. @@ -625,9 +619,9 @@ //! //! <b>Note</b>: Invalidates the iterators (but not the references) to the //! erased elements. - iterator erase(const_iterator b, const_iterator e, difference_type n) + iterator erase(const_iterator b, const_iterator e, size_type n) { - BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(b, e) == difference_type(n)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(node_algorithms::distance(b.pointed_node(), e.pointed_node()) == n); if(safemode_or_autounlink || constant_time_size){ return this->erase_and_dispose(b, e, detail::null_disposer()); } @@ -663,7 +657,7 @@ this->priv_size_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(this->get_real_value_traits().to_value_ptr(to_erase)); + disposer(this->priv_value_traits().to_value_ptr(to_erase)); return i.unconst(); } @@ -697,7 +691,7 @@ bp = node_traits::get_next(bp); if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); this->priv_size_traits().decrement(); } return e.unconst(); @@ -743,7 +737,7 @@ ++it; if(safemode_or_autounlink) node_algorithms::init(to_erase); - disposer(get_real_value_traits().to_value_ptr(to_erase)); + disposer(priv_value_traits().to_value_ptr(to_erase)); } node_algorithms::init_header(this->get_root_node()); this->priv_size_traits().set_size(0); @@ -789,12 +783,12 @@ //! <b>Note</b>: Does not affect the validity of iterators and references. iterator insert(const_iterator p, reference value) { - node_ptr to_insert = this->get_real_value_traits().to_node_ptr(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)); node_algorithms::link_before(p.pointed_node(), to_insert); this->priv_size_traits().increment(); - return iterator(to_insert, real_value_traits_ptr()); + return iterator(to_insert, this->priv_value_traits_ptr()); } //! <b>Requires</b>: Dereferencing iterator must yield @@ -887,7 +881,7 @@ //! new_ele must point to an element contained in list x. //! //! <b>Effects</b>: Transfers the value pointed by new_ele, from list x to this list, - //! before the the element pointed by p. No destructors or copy constructors are called. + //! before the element pointed by p. No destructors or copy constructors are called. //! If p == new_ele or p == ++new_ele, this function is a null operation. //! //! <b>Throws</b>: Nothing. @@ -907,7 +901,7 @@ //! f and e must point to elements contained in list x. //! //! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list, - //! before the the element pointed by p. No destructors or copy constructors are called. + //! before the element pointed by p. No destructors or copy constructors are called. //! //! <b>Throws</b>: Nothing. //! @@ -919,17 +913,17 @@ void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e) { if(constant_time_size) - this->splice(p, x, f, e, std::distance(f, e)); + this->splice(p, x, f, e, node_algorithms::distance(f.pointed_node(), e.pointed_node())); else - this->splice(p, x, f, e, 1);//distance is a dummy value + this->splice(p, x, f, e, 1);//intrusive::iterator_distance is a dummy value } //! <b>Requires</b>: p must be a valid iterator of *this. //! f and e must point to elements contained in list x. - //! n == std::distance(f, e) + //! n == distance(f, e) //! //! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list, - //! before the the element pointed by p. No destructors or copy constructors are called. + //! before the element pointed by p. No destructors or copy constructors are called. //! //! <b>Throws</b>: Nothing. //! @@ -937,11 +931,11 @@ //! //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this //! list. Iterators of this list and all the references are not invalidated. - void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, difference_type n) + void splice(const_iterator p, list_impl&x, const_iterator f, const_iterator e, size_type n) { if(n){ if(constant_time_size){ - BOOST_INTRUSIVE_INVARIANT_ASSERT(n == std::distance(f, e)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(n == node_algorithms::distance(f.pointed_node(), e.pointed_node())); node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node()); size_traits &thist = this->priv_size_traits(); size_traits &xt = x.priv_size_traits(); @@ -957,7 +951,7 @@ //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. //! The sort is stable, that is, the relative order of equivalent elements is preserved. //! - //! <b>Throws</b>: If real_value_traits::node_traits::node + //! <b>Throws</b>: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or std::less<value_type> throws. Basic guarantee. //! @@ -973,7 +967,7 @@ //! <b>Effects</b>: This function sorts the list *this according to p. The sort is //! stable, that is, the relative order of equivalent elements is preserved. //! - //! <b>Throws</b>: If real_value_traits::node_traits::node + //! <b>Throws</b>: If value_traits::node_traits::node //! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! or the predicate throws. Basic guarantee. //! @@ -1109,7 +1103,17 @@ //! and iterators to elements that are not removed remain valid. template<class Pred> void remove_if(Pred pred) - { this->remove_and_dispose_if(pred, detail::null_disposer()); } + { + const node_ptr root_node = this->get_root_node(); + typename node_algorithms::stable_partition_info info; + node_algorithms::stable_partition + (node_traits::get_next(root_node), root_node, detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info); + //Invariants preserved by stable_partition so erase can be safely called + //The first element might have changed so calculate it again + this->erase( const_iterator(node_traits::get_next(root_node), this->priv_value_traits_ptr()) + , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr()) + , info.num_1st_partition); + } //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw. //! @@ -1126,16 +1130,15 @@ template<class Pred, class Disposer> void remove_and_dispose_if(Pred pred, Disposer disposer) { - const_iterator cur(this->cbegin()); - const_iterator last(this->cend()); - while(cur != last) { - if(pred(*cur)){ - cur = this->erase_and_dispose(cur, disposer); - } - else{ - ++cur; - } - } + const node_ptr root_node = this->get_root_node(); + typename node_algorithms::stable_partition_info info; + node_algorithms::stable_partition + (node_traits::get_next(root_node), root_node, detail::key_nodeptr_comp<Pred, value_traits>(pred, &this->priv_value_traits()), info); + //Invariants preserved by stable_partition so erase can be safely called + //The first element might have changed so calculate it again + this->erase_and_dispose( const_iterator(node_traits::get_next(root_node), this->priv_value_traits_ptr()) + , const_iterator(info.beg_2st_partition, this->priv_value_traits_ptr()) + , disposer); } //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent @@ -1227,8 +1230,8 @@ static iterator s_iterator_to(reference value) { BOOST_STATIC_ASSERT((!stateful_value_traits)); - BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value))); - return iterator(real_value_traits::to_node_ptr(value), const_real_value_traits_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value))); + return iterator(value_traits::to_node_ptr(value), const_value_traits_ptr()); } //! <b>Requires</b>: value must be a const reference to a value inserted in a list. @@ -1245,8 +1248,9 @@ static const_iterator s_iterator_to(const_reference value) { BOOST_STATIC_ASSERT((!stateful_value_traits)); - BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value)))); - return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr()); + reference r =*detail::uncast(pointer_traits<const_pointer>::pointer_to(value)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(r))); + return const_iterator(value_traits::to_node_ptr(r), const_value_traits_ptr()); } //! <b>Requires</b>: value must be a reference to a value inserted in a list. @@ -1260,8 +1264,8 @@ //! <b>Note</b>: Iterators and references are not invalidated. iterator iterator_to(reference value) { - BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value))); - return iterator(real_value_traits::to_node_ptr(value), real_value_traits_ptr()); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value))); + return iterator(this->priv_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); } //! <b>Requires</b>: value must be a const reference to a value inserted in a list. @@ -1275,8 +1279,45 @@ //! <b>Note</b>: Iterators and references are not invalidated. const_iterator iterator_to(const_reference value) const { - BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value)))); - return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), real_value_traits_ptr()); + reference r = *detail::uncast(pointer_traits<const_pointer>::pointer_to(value)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(r))); + return const_iterator(this->priv_value_traits().to_node_ptr(r), this->priv_value_traits_ptr()); + } + + //! <b>Effects</b>: Asserts the integrity of the container. + //! + //! <b>Complexity</b>: Linear time. + //! + //! <b>Note</b>: The method has no effect when asserts are turned off (e.g., with NDEBUG). + //! Experimental function, interface might change in future versions. + void check() const + { + const_node_ptr header_ptr = get_root_node(); + // header's next and prev are never null + BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_next(header_ptr)); + BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_previous(header_ptr)); + // header's next and prev either both point to header (empty list) or neither does + BOOST_INTRUSIVE_INVARIANT_ASSERT((node_traits::get_next(header_ptr) == header_ptr) + == (node_traits::get_previous(header_ptr) == header_ptr)); + if (node_traits::get_next(header_ptr) == header_ptr) + { + if (constant_time_size) + BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == 0); + return; + } + size_t node_count = 0; + const_node_ptr p = header_ptr; + while (true) + { + const_node_ptr next_p = node_traits::get_next(p); + BOOST_INTRUSIVE_INVARIANT_ASSERT(next_p); + BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_previous(next_p) == p); + p = next_p; + if (p == header_ptr) break; + ++node_count; + } + if (constant_time_size) + BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count); } /// @cond @@ -1284,8 +1325,11 @@ private: static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator) { - root_plus_size *r = detail::parent_from_member<root_plus_size, node> - ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &root_plus_size::root_); + BOOST_STATIC_ASSERT((has_container_from_iterator)); + node_ptr p = end_iterator.pointed_node(); + header_holder_type* h = header_holder_type::get_holder(p); + root_plus_size* r = detail::parent_from_member + < root_plus_size, header_holder_type>(h, &root_plus_size::m_header); data_t *d = detail::parent_from_member<data_t, root_plus_size> ( r, &data_t::root_plus_size_); list_impl *s = detail::parent_from_member<list_impl, data_t>(d, &list_impl::data_); @@ -1297,117 +1341,98 @@ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template<class T, class ...Options> #else -template <class ValueTraits, class SizeType, bool ConstantTimeSize> +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> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y) +(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) #endif -{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } +{ 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> +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> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y) +(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) #endif { - typedef list_impl<ValueTraits, SizeType, ConstantTimeSize> list_type; - typedef typename list_type::const_iterator const_iterator; + 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; } - const_iterator end1 = x.end(); - - const_iterator i1 = x.begin(); - const_iterator i2 = y.begin(); - if(C){ - while (i1 != end1 && *i1 == *i2) { - ++i1; - ++i2; - } - return i1 == end1; - } - else{ - const_iterator end2 = y.end(); - while (i1 != end1 && i2 != end2 && *i1 == *i2) { - ++i1; - ++i2; - } - return i1 == end1 && i2 == end2; - } + 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> +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> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y) +(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> +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> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y) +(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> +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> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y) +(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> +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> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y) +(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> +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> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize> &y) +(list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y) #endif { x.swap(y); } @@ -1416,7 +1441,7 @@ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) template<class T, class ...Options> #else -template<class T, class O1 = void, class O2 = void, class O3 = void> +template<class T, class O1 = void, class O2 = void, class O3 = void, class O4 = void> #endif struct make_list { @@ -1424,7 +1449,7 @@ typedef typename pack_options < list_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3 + O1, O2, O3, O4 #else Options... #endif @@ -1432,12 +1457,12 @@ typedef typename detail::get_value_traits <T, typename packed_options::proto_value_traits>::type value_traits; - typedef list_impl < value_traits, typename packed_options::size_type, - packed_options::constant_time_size + packed_options::constant_time_size, + typename packed_options::header_holder_type > implementation_defined; /// @endcond typedef implementation_defined type; @@ -1447,14 +1472,14 @@ #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template<class T, class O1, class O2, class O3> +template<class T, class O1, class O2, class O3, class O4> #else template<class T, class ...Options> #endif class list : public make_list<T, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3 + O1, O2, O3, O4 #else Options... #endif @@ -1463,14 +1488,13 @@ typedef typename make_list <T, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3 + O1, O2, O3, O4 #else Options... #endif >::type Base; - 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<typename real_value_traits::value_type, T>::value)); + BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value)); BOOST_MOVABLE_BUT_NOT_COPYABLE(list) public: @@ -1488,11 +1512,11 @@ {} list(BOOST_RV_REF(list) x) - : Base(::boost::move(static_cast<Base&>(x))) + : Base(BOOST_MOVE_BASE(Base, x)) {} list& operator=(BOOST_RV_REF(list) x) - { return static_cast<list &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); } + { return static_cast<list &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } static list &container_from_end_iterator(iterator end_iterator) { return static_cast<list &>(Base::container_from_end_iterator(end_iterator)); }