Merge branch 'develop'

This commit is contained in:
Ion Gaztañaga
2014-02-15 00:21:36 +01:00
8 changed files with 439 additions and 376 deletions

View File

@@ -36,11 +36,11 @@ struct stateful_value_traits
{} {}
///Note: non static functions! ///Note: non static functions!
node_ptr to_node_ptr (value_type &value) node_ptr to_node_ptr (value_type &value) const
{ return this->nodes_ + (&value - this->ids_); } { return this->nodes_ + (&value - this->ids_); }
const_node_ptr to_node_ptr (const value_type &value) const const_node_ptr to_node_ptr (const value_type &value) const
{ return this->nodes_ + (&value - this->ids_); } { return this->nodes_ + (&value - this->ids_); }
pointer to_value_ptr(node_ptr n) pointer to_value_ptr(node_ptr n) const
{ return this->ids_ + (n - this->nodes_); } { return this->ids_ + (n - this->nodes_); }
const_pointer to_value_ptr(const_node_ptr n) const const_pointer to_value_ptr(const_node_ptr n) const
{ return this->ids_ + (n - this->nodes_); } { return this->ids_ + (n - this->nodes_); }

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,8 @@
#define BOOST_INTRUSIVE_LIST_HPP #define BOOST_INTRUSIVE_LIST_HPP
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/list_hook.hpp> #include <boost/intrusive/list_hook.hpp>
#include <boost/intrusive/circular_list_algorithms.hpp> #include <boost/intrusive/circular_list_algorithms.hpp>
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
@@ -65,37 +65,32 @@ template <class ValueTraits, class SizeType, bool ConstantTimeSize>
class list_impl class list_impl
: private detail::clear_on_destructor_base : private detail::clear_on_destructor_base
< list_impl<ValueTraits, SizeType, ConstantTimeSize> < list_impl<ValueTraits, SizeType, ConstantTimeSize>
, is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value , is_safe_autounlink<ValueTraits::link_mode>::value
> >
{ {
template<class C, bool> friend class detail::clear_on_destructor_base; template<class C, bool> friend class detail::clear_on_destructor_base;
//Public typedefs //Public typedefs
public: public:
typedef ValueTraits value_traits; typedef ValueTraits value_traits;
/// @cond typedef typename value_traits::pointer pointer;
static const bool external_value_traits = typedef typename value_traits::const_pointer const_pointer;
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 typename pointer_traits<pointer>::element_type value_type; typedef typename pointer_traits<pointer>::element_type value_type;
typedef typename pointer_traits<pointer>::reference reference; typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference; typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type; typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef SizeType size_type; typedef SizeType size_type;
typedef list_iterator<real_value_traits, false> iterator; typedef list_iterator<value_traits, false> iterator;
typedef list_iterator<real_value_traits, true> const_iterator; typedef list_iterator<value_traits, true> const_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator; typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator; typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
typedef typename real_value_traits::node_traits node_traits; typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node node; typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr;
typedef circular_list_algorithms<node_traits> node_algorithms; typedef circular_list_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = ConstantTimeSize; 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;
/// @cond /// @cond
@@ -105,11 +100,11 @@ class list_impl
//noncopyable //noncopyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl) 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! //Constant-time size is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(constant_time_size && 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() node_ptr get_root_node()
@@ -139,54 +134,27 @@ class list_impl
const size_traits &priv_size_traits() const const size_traits &priv_size_traits() const
{ return data_.root_plus_size_; } { 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 const value_traits &priv_value_traits() const
{ return data_; } { return data_; }
value_traits &priv_value_traits() value_traits &priv_value_traits()
{ return data_; } { return data_; }
protected: typedef typename pointer_traits<node_ptr>::template
node &prot_root_node() rebind_pointer<value_traits const>::type const_value_traits_ptr;
{ return data_.root_plus_size_.root_; }
node const &prot_root_node() const const_value_traits_ptr value_traits_ptr() const
{ return data_.root_plus_size_.root_; } { return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); }
void prot_set_size(size_type s)
{ data_.root_plus_size_.set_size(s); }
/// @endcond /// @endcond
public: 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>Effects</b>: constructs an empty list.
//! //!
//! <b>Complexity</b>: Constant //! <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). //! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
explicit list_impl(const value_traits &v_traits = value_traits()) explicit list_impl(const value_traits &v_traits = value_traits())
: data_(v_traits) : data_(v_traits)
@@ -201,7 +169,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Linear in std::distance(b, e). No copy constructors are called. //! <b>Complexity</b>: Linear in std::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). //! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
template<class Iterator> template<class Iterator>
list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits()) list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
@@ -253,7 +221,7 @@ class list_impl
//! <b>Note</b>: Does not affect the validity of iterators and references. //! <b>Note</b>: Does not affect the validity of iterators and references.
void push_back(reference value) 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) if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
node_algorithms::link_before(this->get_root_node(), to_insert); node_algorithms::link_before(this->get_root_node(), to_insert);
@@ -272,7 +240,7 @@ class list_impl
//! <b>Note</b>: Does not affect the validity of iterators and references. //! <b>Note</b>: Does not affect the validity of iterators and references.
void push_front(reference value) 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) if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); 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); node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
@@ -309,7 +277,7 @@ class list_impl
this->priv_size_traits().decrement(); this->priv_size_traits().decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); 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. //! <b>Effects</b>: Erases the first element of the list.
@@ -342,7 +310,7 @@ class list_impl
this->priv_size_traits().decrement(); this->priv_size_traits().decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); 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. //! <b>Effects</b>: Returns a reference to the first element of the list.
@@ -351,7 +319,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference front() 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. //! <b>Effects</b>: Returns a const_reference to the first element of the list.
//! //!
@@ -359,7 +327,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference front() const 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(detail::uncast(node_traits::get_next(this->get_root_node()))); }
//! <b>Effects</b>: Returns a reference to the last element of the list. //! <b>Effects</b>: Returns a reference to the last element of the list.
//! //!
@@ -367,7 +335,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference back() 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. //! <b>Effects</b>: Returns a const_reference to the last element of the list.
//! //!
@@ -375,7 +343,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference back() const 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. //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
//! //!
@@ -383,7 +351,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
iterator begin() 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()), value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//! //!
@@ -399,7 +367,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator cbegin() const 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()), value_traits_ptr()); }
//! <b>Effects</b>: Returns an iterator to the end of the list. //! <b>Effects</b>: Returns an iterator to the end of the list.
//! //!
@@ -407,7 +375,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
iterator end() iterator end()
{ return iterator(this->get_root_node(), real_value_traits_ptr()); } { return iterator(this->get_root_node(), value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list. //! <b>Effects</b>: Returns a const_iterator to the end of the list.
//! //!
@@ -423,7 +391,7 @@ class list_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator cend() const 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()), value_traits_ptr()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
//! of the reversed list. //! of the reversed list.
@@ -663,7 +631,7 @@ class list_impl
this->priv_size_traits().decrement(); this->priv_size_traits().decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); 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(); return i.unconst();
} }
@@ -697,7 +665,7 @@ class list_impl
bp = node_traits::get_next(bp); bp = node_traits::get_next(bp);
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); 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(); this->priv_size_traits().decrement();
} }
return e.unconst(); return e.unconst();
@@ -743,7 +711,7 @@ class list_impl
++it; ++it;
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); 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()); node_algorithms::init_header(this->get_root_node());
this->priv_size_traits().set_size(0); this->priv_size_traits().set_size(0);
@@ -789,12 +757,12 @@ class list_impl
//! <b>Note</b>: Does not affect the validity of iterators and references. //! <b>Note</b>: Does not affect the validity of iterators and references.
iterator insert(const_iterator p, reference value) 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) if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
node_algorithms::link_before(p.pointed_node(), to_insert); node_algorithms::link_before(p.pointed_node(), to_insert);
this->priv_size_traits().increment(); this->priv_size_traits().increment();
return iterator(to_insert, real_value_traits_ptr()); return iterator(to_insert, value_traits_ptr());
} }
//! <b>Requires</b>: Dereferencing iterator must yield //! <b>Requires</b>: Dereferencing iterator must yield
@@ -887,7 +855,7 @@ class list_impl
//! new_ele must point to an element contained in list x. //! 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, //! <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. //! If p == new_ele or p == ++new_ele, this function is a null operation.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
@@ -907,7 +875,7 @@ class list_impl
//! f and e must point to elements contained in list x. //! 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, //! <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. //! <b>Throws</b>: Nothing.
//! //!
@@ -929,7 +897,7 @@ class list_impl
//! n == std::distance(f, e) //! n == std::distance(f, e)
//! //!
//! <b>Effects</b>: Transfers the range pointed by f and e from list x to this list, //! <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. //! <b>Throws</b>: Nothing.
//! //!
@@ -957,7 +925,7 @@ class list_impl
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. //! <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. //! 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) //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or std::less<value_type> throws. Basic guarantee. //! or std::less<value_type> throws. Basic guarantee.
//! //!
@@ -973,7 +941,7 @@ class list_impl
//! <b>Effects</b>: This function sorts the list *this according to p. The sort is //! <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. //! 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) //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the predicate throws. Basic guarantee. //! or the predicate throws. Basic guarantee.
//! //!
@@ -1227,8 +1195,8 @@ class list_impl
static iterator s_iterator_to(reference value) static iterator s_iterator_to(reference value)
{ {
BOOST_STATIC_ASSERT((!stateful_value_traits)); BOOST_STATIC_ASSERT((!stateful_value_traits));
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value)));
return iterator(real_value_traits::to_node_ptr(value), const_real_value_traits_ptr()); 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. //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@@ -1245,8 +1213,8 @@ class list_impl
static const_iterator s_iterator_to(const_reference value) static const_iterator s_iterator_to(const_reference value)
{ {
BOOST_STATIC_ASSERT((!stateful_value_traits)); BOOST_STATIC_ASSERT((!stateful_value_traits));
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value)))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(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()); return const_iterator(value_traits::to_node_ptr(const_cast<reference> (value)), const_value_traits_ptr());
} }
//! <b>Requires</b>: value must be a reference to a value inserted in a list. //! <b>Requires</b>: value must be a reference to a value inserted in a list.
@@ -1260,8 +1228,8 @@ class list_impl
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
iterator iterator_to(reference value) iterator iterator_to(reference value)
{ {
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value)));
return iterator(real_value_traits::to_node_ptr(value), real_value_traits_ptr()); return iterator(this->priv_value_traits().to_node_ptr(value), value_traits_ptr());
} }
//! <b>Requires</b>: value must be a const reference to a value inserted in a list. //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@@ -1275,8 +1243,8 @@ class list_impl
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
const_iterator iterator_to(const_reference value) const 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)))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_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()); return const_iterator(this->priv_value_traits().to_node_ptr(const_cast<reference> (value)), value_traits_ptr());
} }
/// @cond /// @cond
@@ -1468,9 +1436,8 @@ class list
Options... Options...
#endif #endif
>::type Base; >::type Base;
typedef typename Base::real_value_traits real_value_traits;
//Assert if passed value traits are compatible with the type //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) BOOST_MOVABLE_BUT_NOT_COPYABLE(list)
public: public:

View File

@@ -15,9 +15,9 @@
#define BOOST_INTRUSIVE_SLIST_HPP #define BOOST_INTRUSIVE_SLIST_HPP
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/intrusive/detail/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/slist_hook.hpp> #include <boost/intrusive/slist_hook.hpp>
#include <boost/intrusive/circular_slist_algorithms.hpp> #include <boost/intrusive/circular_slist_algorithms.hpp>
#include <boost/intrusive/linear_slist_algorithms.hpp> #include <boost/intrusive/linear_slist_algorithms.hpp>
@@ -101,34 +101,29 @@ template<class ValueTraits, class SizeType, std::size_t BoolFlags>
class slist_impl class slist_impl
: private detail::clear_on_destructor_base : private detail::clear_on_destructor_base
< slist_impl<ValueTraits, SizeType, BoolFlags> < slist_impl<ValueTraits, SizeType, BoolFlags>
, is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value , is_safe_autounlink<ValueTraits::link_mode>::value
> >
{ {
template<class C, bool> friend class detail::clear_on_destructor_base; template<class C, bool> friend class detail::clear_on_destructor_base;
//Public typedefs //Public typedefs
public: public:
typedef ValueTraits value_traits; typedef ValueTraits value_traits;
/// @cond typedef typename value_traits::pointer pointer;
static const bool external_value_traits = typedef typename value_traits::const_pointer const_pointer;
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 typename pointer_traits<pointer>::element_type value_type; typedef typename pointer_traits<pointer>::element_type value_type;
typedef typename pointer_traits<pointer>::reference reference; typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference; typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type; typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef SizeType size_type; typedef SizeType size_type;
typedef slist_iterator<real_value_traits, false> iterator; typedef slist_iterator<value_traits, false> iterator;
typedef slist_iterator<real_value_traits, true> const_iterator; typedef slist_iterator<value_traits, true> const_iterator;
typedef typename real_value_traits::node_traits node_traits; typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node node; typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr;
static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos); static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos);
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 linear = 0 != (BoolFlags & slist_bool_flags::linear_pos); static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos);
static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos); static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos);
@@ -145,14 +140,14 @@ class slist_impl
//noncopyable //noncopyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl) BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_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! //Constant-time size is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink))); BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
//Linear singly linked lists are incompatible with auto-unlink hooks! //Linear singly linked lists are incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(linear && ((int)real_value_traits::link_mode == (int)auto_unlink))); BOOST_STATIC_ASSERT(!(linear && ((int)value_traits::link_mode == (int)auto_unlink)));
//A list with cached last node is incompatible with auto-unlink hooks! //A list with cached last node is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink))); BOOST_STATIC_ASSERT(!(cache_last && ((int)value_traits::link_mode == (int)auto_unlink)));
node_ptr get_end_node() node_ptr get_end_node()
{ return node_ptr(linear ? node_ptr() : this->get_root_node()); } { return node_ptr(linear ? node_ptr() : this->get_root_node()); }
@@ -230,18 +225,6 @@ class slist_impl
const size_traits &priv_size_traits() const const size_traits &priv_size_traits() const
{ return data_.root_plus_size_; } { 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 const value_traits &priv_value_traits() const
{ return data_; } { return data_; }
@@ -258,20 +241,15 @@ class slist_impl
void prot_set_size(size_type s) void prot_set_size(size_type s)
{ data_.root_plus_size_.set_size(s); } { data_.root_plus_size_.set_size(s); }
/// @endcond
public: public:
const real_value_traits &get_real_value_traits() const typedef typename pointer_traits<node_ptr>::template
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); } rebind_pointer<const value_traits>::type const_value_traits_ptr;
real_value_traits &get_real_value_traits() const_value_traits_ptr value_traits_ptr() const
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); } { return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); }
typedef typename pointer_traits<node_ptr>::template rebind_pointer<const real_value_traits>::type const_real_value_traits_ptr; /// @endcond
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()); }
public: public:
@@ -403,7 +381,7 @@ class slist_impl
++it; ++it;
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); 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->set_default_constructed_state(); this->set_default_constructed_state();
} }
@@ -420,7 +398,7 @@ class slist_impl
//! <b>Note</b>: Does not affect the validity of iterators and references. //! <b>Note</b>: Does not affect the validity of iterators and references.
void push_front(reference value) 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) if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
if(cache_last){ if(cache_last){
@@ -446,7 +424,7 @@ class slist_impl
void push_back(reference value) void push_back(reference value)
{ {
BOOST_STATIC_ASSERT((cache_last)); BOOST_STATIC_ASSERT((cache_last));
node_ptr n = get_real_value_traits().to_node_ptr(value); node_ptr n = priv_value_traits().to_node_ptr(value);
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
node_algorithms::link_after(this->get_last_node(), n); node_algorithms::link_after(this->get_last_node(), n);
@@ -485,7 +463,7 @@ class slist_impl
this->priv_size_traits().decrement(); this->priv_size_traits().decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase)); disposer(priv_value_traits().to_value_ptr(to_erase));
if(cache_last){ if(cache_last){
if(this->empty()){ if(this->empty()){
this->set_last_node(this->get_root_node()); this->set_last_node(this->get_root_node());
@@ -499,7 +477,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference front() reference front()
{ return *this->get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); } { return *this->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. //! <b>Effects</b>: Returns a const_reference to the first element of the list.
//! //!
@@ -507,7 +485,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference front() const const_reference front() const
{ return *this->get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); } { return *this->priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
//! <b>Effects</b>: Returns a reference to the last element of the list. //! <b>Effects</b>: Returns a reference to the last element of the list.
//! //!
@@ -520,7 +498,7 @@ class slist_impl
reference back() reference back()
{ {
BOOST_STATIC_ASSERT((cache_last)); BOOST_STATIC_ASSERT((cache_last));
return *this->get_real_value_traits().to_value_ptr(this->get_last_node()); return *this->priv_value_traits().to_value_ptr(this->get_last_node());
} }
//! <b>Effects</b>: Returns a const_reference to the last element of the list. //! <b>Effects</b>: Returns a const_reference to the last element of the list.
@@ -534,7 +512,7 @@ class slist_impl
const_reference back() const const_reference back() const
{ {
BOOST_STATIC_ASSERT((cache_last)); BOOST_STATIC_ASSERT((cache_last));
return *this->get_real_value_traits().to_value_ptr(this->get_last_node()); return *this->priv_value_traits().to_value_ptr(this->get_last_node());
} }
//! <b>Effects</b>: Returns an iterator to the first element contained in the list. //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
@@ -543,7 +521,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
iterator begin() iterator begin()
{ return iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } { return iterator (node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//! //!
@@ -551,7 +529,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator begin() const const_iterator begin() const
{ return const_iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } { return const_iterator (node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list. //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//! //!
@@ -559,7 +537,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator cbegin() const const_iterator cbegin() const
{ return const_iterator(node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); } { return const_iterator(node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns an iterator to the end of the list. //! <b>Effects</b>: Returns an iterator to the end of the list.
//! //!
@@ -567,7 +545,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
iterator end() iterator end()
{ return iterator(this->get_end_node(), this->real_value_traits_ptr()); } { return iterator(this->get_end_node(), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list. //! <b>Effects</b>: Returns a const_iterator to the end of the list.
//! //!
@@ -575,7 +553,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator end() const const_iterator end() const
{ return const_iterator(detail::uncast(this->get_end_node()), this->real_value_traits_ptr()); } { return const_iterator(detail::uncast(this->get_end_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list. //! <b>Effects</b>: Returns a const_iterator to the end of the list.
//! //!
@@ -592,7 +570,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
iterator before_begin() iterator before_begin()
{ return iterator(this->get_root_node(), this->real_value_traits_ptr()); } { return iterator(this->get_root_node(), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns an iterator that points to a position //! <b>Effects</b>: Returns an iterator that points to a position
//! before the first element. Equivalent to "end()" //! before the first element. Equivalent to "end()"
@@ -601,7 +579,7 @@ class slist_impl
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_iterator before_begin() const const_iterator before_begin() const
{ return const_iterator(detail::uncast(this->get_root_node()), this->real_value_traits_ptr()); } { return const_iterator(detail::uncast(this->get_root_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns an iterator that points to a position //! <b>Effects</b>: Returns an iterator that points to a position
//! before the first element. Equivalent to "end()" //! before the first element. Equivalent to "end()"
@@ -623,7 +601,7 @@ class slist_impl
{ {
//This function shall not be used if cache_last is not true //This function shall not be used if cache_last is not true
BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
return iterator (this->get_last_node(), this->real_value_traits_ptr()); return iterator (this->get_last_node(), this->value_traits_ptr());
} }
//! <b>Effects</b>: Returns a const_iterator to the last element contained in the list. //! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
@@ -637,7 +615,7 @@ class slist_impl
{ {
//This function shall not be used if cache_last is not true //This function shall not be used if cache_last is not true
BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last); BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
return const_iterator (this->get_last_node(), this->real_value_traits_ptr()); return const_iterator (this->get_last_node(), this->value_traits_ptr());
} }
//! <b>Effects</b>: Returns a const_iterator to the last element contained in the list. //! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
@@ -648,7 +626,7 @@ class slist_impl
//! //!
//! <b>Note</b>: This function is present only if cached_last<> option is true. //! <b>Note</b>: This function is present only if cached_last<> option is true.
const_iterator clast() const const_iterator clast() const
{ return const_iterator(this->get_last_node(), this->real_value_traits_ptr()); } { return const_iterator(this->get_last_node(), this->value_traits_ptr()); }
//! <b>Precondition</b>: end_iterator must be a valid end iterator //! <b>Precondition</b>: end_iterator must be a valid end iterator
//! of slist. //! of slist.
@@ -788,7 +766,7 @@ class slist_impl
//! <b>Note</b>: Does not affect the validity of iterators and references. //! <b>Note</b>: Does not affect the validity of iterators and references.
iterator insert_after(const_iterator prev_p, reference value) iterator insert_after(const_iterator prev_p, reference value)
{ {
node_ptr n = get_real_value_traits().to_node_ptr(value); node_ptr n = priv_value_traits().to_node_ptr(value);
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
node_ptr prev_n(prev_p.pointed_node()); node_ptr prev_n(prev_p.pointed_node());
@@ -797,7 +775,7 @@ class slist_impl
this->set_last_node(n); this->set_last_node(n);
} }
this->priv_size_traits().increment(); this->priv_size_traits().increment();
return iterator (n, this->real_value_traits_ptr()); return iterator (n, this->value_traits_ptr());
} }
//! <b>Requires</b>: Dereferencing iterator must yield //! <b>Requires</b>: Dereferencing iterator must yield
@@ -819,7 +797,7 @@ class slist_impl
size_type count = 0; size_type count = 0;
node_ptr prev_n(prev_p.pointed_node()); node_ptr prev_n(prev_p.pointed_node());
for (; f != l; ++f, ++count){ for (; f != l; ++f, ++count){
const node_ptr n = get_real_value_traits().to_node_ptr(*f); const node_ptr n = priv_value_traits().to_node_ptr(*f);
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
node_algorithms::link_after(prev_n, n); node_algorithms::link_after(prev_n, n);
@@ -1026,7 +1004,7 @@ class slist_impl
} }
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); 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(); this->priv_size_traits().decrement();
return it.unconst(); return it.unconst();
} }
@@ -1045,7 +1023,7 @@ class slist_impl
node_algorithms::unlink_after(prev_n); node_algorithms::unlink_after(prev_n);
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); node_algorithms::init(to_erase);
disposer(real_value_traits::to_value_ptr(to_erase)); disposer(value_traits::to_value_ptr(to_erase));
return it.unconst(); return it.unconst();
} }
@@ -1079,7 +1057,7 @@ class slist_impl
fp = node_traits::get_next(fp); fp = node_traits::get_next(fp);
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); 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(); this->priv_size_traits().decrement();
} }
if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){ if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){
@@ -1691,8 +1669,7 @@ class slist_impl
static iterator s_iterator_to(reference value) static iterator s_iterator_to(reference value)
{ {
BOOST_STATIC_ASSERT((!stateful_value_traits)); BOOST_STATIC_ASSERT((!stateful_value_traits));
//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());
return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr());
} }
//! <b>Requires</b>: value must be a const reference to a value inserted in a list. //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@@ -1709,8 +1686,7 @@ class slist_impl
static const_iterator s_iterator_to(const_reference value) static const_iterator s_iterator_to(const_reference value)
{ {
BOOST_STATIC_ASSERT((!stateful_value_traits)); BOOST_STATIC_ASSERT((!stateful_value_traits));
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value)))); return const_iterator(value_traits::to_node_ptr(const_cast<reference> (value)), const_value_traits_ptr());
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
} }
//! <b>Requires</b>: value must be a reference to a value inserted in a list. //! <b>Requires</b>: value must be a reference to a value inserted in a list.
@@ -1724,8 +1700,8 @@ class slist_impl
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
iterator iterator_to(reference value) iterator iterator_to(reference value)
{ {
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(value)));
return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr()); return iterator (this->priv_value_traits().to_node_ptr(value), this->value_traits_ptr());
} }
//! <b>Requires</b>: value must be a const reference to a value inserted in a list. //! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@@ -1739,8 +1715,8 @@ class slist_impl
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
const_iterator iterator_to(const_reference value) const const_iterator iterator_to(const_reference value) const
{ {
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value)))); BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(this->priv_value_traits().to_node_ptr(const_cast<reference> (value))));
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this->real_value_traits_ptr()); return const_iterator(this->priv_value_traits().to_node_ptr(const_cast<reference> (value)), this->value_traits_ptr());
} }
//! <b>Returns</b>: The iterator to the element before i in the list. //! <b>Returns</b>: The iterator to the element before i in the list.
@@ -1789,11 +1765,11 @@ class slist_impl
const_iterator previous(const_iterator prev_from, const_iterator i) const const_iterator previous(const_iterator prev_from, const_iterator i) const
{ {
if(cache_last && (i.pointed_node() == this->get_end_node())){ if(cache_last && (i.pointed_node() == this->get_end_node())){
return const_iterator(detail::uncast(this->get_last_node()), this->real_value_traits_ptr()); return const_iterator(detail::uncast(this->get_last_node()), this->value_traits_ptr());
} }
return const_iterator return const_iterator
(node_algorithms::get_previous_node (node_algorithms::get_previous_node
(prev_from.pointed_node(), i.pointed_node()), this->real_value_traits_ptr()); (prev_from.pointed_node(), i.pointed_node()), this->value_traits_ptr());
} }
///@cond ///@cond
@@ -1844,8 +1820,8 @@ class slist_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0); BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0);
BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_INTRUSIVE_INVARIANT_ASSERT
(size_type(std::distance (size_type(std::distance
( iterator(f, this->real_value_traits_ptr()) ( iterator(f, this->value_traits_ptr())
, iterator(before_l, this->real_value_traits_ptr()))) , iterator(before_l, this->value_traits_ptr())))
+1 == n); +1 == n);
this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l); this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l);
if(constant_time_size){ if(constant_time_size){
@@ -2171,9 +2147,8 @@ class slist
Options... Options...
#endif #endif
>::type Base; >::type Base;
typedef typename Base::real_value_traits real_value_traits;
//Assert if passed value traits are compatible with the type //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(slist) BOOST_MOVABLE_BUT_NOT_COPYABLE(slist)
public: public:

View File

@@ -172,6 +172,12 @@ void test_generic_set<ValueTraits, ContainerDefiner>::test_insert(std::vector<ty
i = set_type::s_iterator_to(values[2]); i = set_type::s_iterator_to(values[2]);
BOOST_TEST (&*i == &values[2]); BOOST_TEST (&*i == &values[2]);
typename set_type::const_iterator ic;
ic = testset.iterator_to (const_cast<const value_type &>(values[2]));
BOOST_TEST (&*ic == &values[2]);
ic = set_type::s_iterator_to (const_cast<const value_type &>(values[2]));
BOOST_TEST (&*ic == &values[2]);
testset.erase (i); testset.erase (i);
{ int init_values [] = { 1, 3, 5 }; { int init_values [] = { 1, 3, 5 };
TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); } TEST_INTRUSIVE_SEQUENCE( init_values, testset.begin() ); }

View File

@@ -234,6 +234,13 @@ void test_list<ValueTraits>
i = list_type::s_iterator_to (values[4]); i = list_type::s_iterator_to (values[4]);
BOOST_TEST (&*i == &values[4]); BOOST_TEST (&*i == &values[4]);
typename list_type::const_iterator ic;
ic = testlist.iterator_to (const_cast<const value_type &>(values[4]));
BOOST_TEST (&*ic == &values[4]);
ic = list_type::s_iterator_to (const_cast<const value_type &>(values[4]));
BOOST_TEST (&*ic == &values[4]);
i = testlist.erase (i); i = testlist.erase (i);
BOOST_TEST (i == testlist.end()); BOOST_TEST (i == testlist.end());

View File

@@ -275,6 +275,13 @@ void test_slist<ValueTraits, Linear, CacheLast>
BOOST_TEST (&*i == &values[4]); BOOST_TEST (&*i == &values[4]);
i = list_type::s_iterator_to (values[4]); i = list_type::s_iterator_to (values[4]);
BOOST_TEST (&*i == &values[4]); BOOST_TEST (&*i == &values[4]);
typename list_type::const_iterator ic;
ic = testlist.iterator_to (const_cast<const value_type &>(values[4]));
BOOST_TEST (&*ic == &values[4]);
ic = list_type::s_iterator_to (const_cast<const value_type &>(values[4]));
BOOST_TEST (&*ic == &values[4]);
i = testlist.previous (i); i = testlist.previous (i);
BOOST_TEST (&*i == &values[0]); BOOST_TEST (&*i == &values[0]);

View File

@@ -57,16 +57,16 @@ struct stateful_value_traits
: values_(vals), node_array_(node_array) : values_(vals), node_array_(node_array)
{} {}
node_ptr to_node_ptr (value_type &value) node_ptr to_node_ptr (value_type &value) const
{ return node_array_ + (&value - values_); } { return node_array_ + (&value - values_); }
const_node_ptr to_node_ptr (const value_type &value) const const_node_ptr to_node_ptr (const value_type &value) const
{ return node_array_ + (&value - values_); } { return node_array_ + (&value - values_); }
pointer to_value_ptr(node_ptr n) pointer to_value_ptr(const node_ptr &n) const
{ return values_ + (n - node_array_); } { return values_ + (n - node_array_); }
const_pointer to_value_ptr(const_node_ptr n) const const_pointer to_value_ptr(const const_node_ptr &n) const
{ return values_ + (n - node_array_); } { return values_ + (n - node_array_); }
pointer values_; pointer values_;
@@ -123,9 +123,18 @@ int main()
; it != itend ; it != itend
; ++it){ ; ++it){
my_list.push_front(*it); my_list.push_front(*it);
if(&*my_list.iterator_to(*it) != &my_list.front())
return 1;
my_slist.push_front(*it); my_slist.push_front(*it);
my_set.insert(*it); if(&*my_slist.iterator_to(*it) != &my_slist.front())
return 1;
Set::iterator sit = my_set.insert(*it).first;
if(&*my_set.iterator_to(*it) != &*sit)
return 1;
Uset::iterator uit = my_uset.insert(*it).first;
my_uset.insert(*it); my_uset.insert(*it);
if(&*my_uset.iterator_to(*it) != &*uit)
return 1;
} }
//Now test lists //Now test lists