forked from boostorg/intrusive
Fixed #9948: remove use of const_cast in intrusive containers.
Added tests for [s_]iterator_to.
This commit is contained in:
@@ -3792,13 +3792,15 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std
|
||||
|
||||
* [*Source breaking]: Removed previously deprecated `xxx_dont_splay` functions from splay containers,
|
||||
`splay_set_base_hook` and `splay_set_member_hook`from splay containers and `bool splay = true`
|
||||
extra parameter is `splaytree_algorithms` functions.
|
||||
extra parameter in `splaytree_algorithms` functions.
|
||||
|
||||
* Fixed bugs:
|
||||
* [@https://svn.boost.org/trac/boost/ticket/8468 #8468: Compile error on visual studio 2010/2012 using vector with custom allocator and aligned types]
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9332 #9332: ['"has_member_function_callable_with.hpp compile error on msvc-12.0"]].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9650 #9650: ['"intrusive list with stateful value traits"]].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9746 #9746: Modern Sun CC compiler detects error in intrusive library header]
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9940 #9940: bad bug in intrusive list with safe_link (or auto_unlink) hooks]
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9948 #9948: remove use of const_cast in intrusive containers]
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9949 #9949: clear header node hooks upon intrusive container destruction]
|
||||
* [@https://svn.boost.org/trac/boost/ticket/9961 #9961: tests for hooks not derived frorm generic_hook]
|
||||
|
||||
|
@@ -1103,6 +1103,13 @@ class hashtable_impl
|
||||
typedef typename pointer_traits
|
||||
<pointer>::template rebind_pointer
|
||||
< bucket_type >::type bucket_ptr;
|
||||
typedef typename pointer_traits
|
||||
<pointer>::template rebind_pointer
|
||||
< const bucket_type >::type const_bucket_ptr;
|
||||
typedef typename pointer_traits
|
||||
<bucket_ptr>::reference bucket_reference;
|
||||
typedef typename pointer_traits
|
||||
<bucket_ptr>::reference const_bucket_reference;
|
||||
typedef typename slist_impl::iterator siterator;
|
||||
typedef typename slist_impl::const_iterator const_siterator;
|
||||
typedef hashtable_iterator<bucket_plus_vtraits_t, false> iterator;
|
||||
@@ -1115,6 +1122,10 @@ class hashtable_impl
|
||||
typedef typename pointer_traits
|
||||
<pointer>::template rebind_pointer
|
||||
< const node >::type const_node_ptr;
|
||||
typedef typename pointer_traits
|
||||
<node_ptr>::reference node_reference;
|
||||
typedef typename pointer_traits
|
||||
<const_node_ptr>::reference const_node_reference;
|
||||
typedef typename slist_impl::node_algorithms node_algorithms;
|
||||
|
||||
static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
|
||||
@@ -2145,7 +2156,9 @@ class hashtable_impl
|
||||
//! <b>Throws</b>: If the internal hash function throws.
|
||||
const_iterator iterator_to(const_reference value) const
|
||||
{
|
||||
siterator sit = bucket_type::s_iterator_to(const_cast<node &>(this->priv_value_to_node(value)));
|
||||
node_reference r = *pointer_traits<node_ptr>::const_cast_from
|
||||
(pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)));
|
||||
siterator sit = bucket_type::s_iterator_to(r);
|
||||
return const_iterator(sit, &this->get_bucket_value_traits());
|
||||
}
|
||||
|
||||
@@ -2183,7 +2196,9 @@ class hashtable_impl
|
||||
static const_local_iterator s_local_iterator_to(const_reference value)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!stateful_value_traits));
|
||||
siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->priv_value_to_node(const_cast<value_type&>(value)));
|
||||
node_reference r = *pointer_traits<node_ptr>::const_cast_from
|
||||
(pointer_traits<const_node_ptr>::pointer_to(((hashtable_impl*)0)->priv_value_to_node(value)));
|
||||
siterator sit = bucket_type::s_iterator_to(r);
|
||||
return const_local_iterator(sit, const_value_traits_ptr());
|
||||
}
|
||||
|
||||
@@ -2213,8 +2228,9 @@ class hashtable_impl
|
||||
//! <b>Throws</b>: Nothing.
|
||||
const_local_iterator local_iterator_to(const_reference value) const
|
||||
{
|
||||
siterator sit = bucket_type::s_iterator_to
|
||||
(const_cast<node &>(this->priv_value_to_node(value)));
|
||||
node_reference r = *pointer_traits<node_ptr>::const_cast_from
|
||||
(pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)));
|
||||
siterator sit = bucket_type::s_iterator_to(r);
|
||||
return const_local_iterator(sit, this->value_traits_ptr());
|
||||
}
|
||||
|
||||
@@ -2314,8 +2330,8 @@ class hashtable_impl
|
||||
//! containing all of the elements in the nth bucket.
|
||||
const_local_iterator cbegin(size_type n) const
|
||||
{
|
||||
siterator sit = const_cast<bucket_type&>(this->priv_bucket_pointer()[n]).begin();
|
||||
return const_local_iterator(sit, this->value_traits_ptr());
|
||||
bucket_reference br = pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n];
|
||||
return const_local_iterator(br.begin(), this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
|
||||
@@ -2359,8 +2375,8 @@ class hashtable_impl
|
||||
//! containing all of the elements in the nth bucket.
|
||||
const_local_iterator cend(size_type n) const
|
||||
{
|
||||
return const_local_iterator ( const_cast<bucket_type&>(this->priv_bucket_pointer()[n]).end()
|
||||
, this->value_traits_ptr());
|
||||
bucket_reference br = pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n];
|
||||
return const_local_iterator ( br.end(), this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: new_bucket_traits can hold a pointer to a new bucket array
|
||||
|
@@ -1213,8 +1213,9 @@ class list_impl
|
||||
static const_iterator s_iterator_to(const_reference value)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!stateful_value_traits));
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value)))));
|
||||
return const_iterator(value_traits::to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), const_value_traits_ptr());
|
||||
reference r =*pointer_traits<pointer>::const_cast_from(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.
|
||||
@@ -1243,8 +1244,9 @@ class list_impl
|
||||
//! <b>Note</b>: Iterators and references are not invalidated.
|
||||
const_iterator iterator_to(const_reference value) const
|
||||
{
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(this->priv_value_traits().to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value)))));
|
||||
return const_iterator(this->priv_value_traits().to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), value_traits_ptr());
|
||||
reference r = *pointer_traits<pointer>::const_cast_from(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), value_traits_ptr());
|
||||
}
|
||||
|
||||
/// @cond
|
||||
|
@@ -1685,7 +1685,8 @@ class slist_impl
|
||||
static const_iterator s_iterator_to(const_reference value)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!stateful_value_traits));
|
||||
return const_iterator(value_traits::to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), const_value_traits_ptr());
|
||||
reference r =*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value));
|
||||
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.
|
||||
@@ -1714,8 +1715,9 @@ class slist_impl
|
||||
//! <b>Note</b>: Iterators and references are not invalidated.
|
||||
const_iterator iterator_to(const_reference value) const
|
||||
{
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT (linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value)))));
|
||||
return const_iterator(this->priv_value_traits().to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), this->value_traits_ptr());
|
||||
reference r =*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value));
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT (linear || !node_algorithms::inited(this->priv_value_traits().to_node_ptr(r)));
|
||||
return const_iterator(this->priv_value_traits().to_node_ptr(r), this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: The iterator to the element before i in the list.
|
||||
|
@@ -232,9 +232,6 @@
|
||||
<File
|
||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\assert.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\clear_on_destructor_base.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\..\boost\intrusive\detail\common_slist_algorithms.hpp">
|
||||
</File>
|
||||
|
@@ -90,6 +90,10 @@ void test_sequence_container(Container & c, Data & d)
|
||||
{
|
||||
typename Data::iterator i = d.begin();
|
||||
c.insert( c.begin(), *i );
|
||||
BOOST_TEST( &*c.iterator_to(*c.begin()) == &*i );
|
||||
BOOST_TEST( &*c.iterator_to(*c.cbegin()) == &*i );
|
||||
BOOST_TEST( &*Container::s_iterator_to(*c.begin()) == &*i );
|
||||
BOOST_TEST( &*Container::s_iterator_to(*c.cbegin()) == &*i );
|
||||
c.insert( c.end(), *(++i) );
|
||||
}
|
||||
BOOST_TEST( c.size() == 2 );
|
||||
@@ -230,6 +234,12 @@ void test_common_unordered_and_associative_container(Container & c, Data & d, bo
|
||||
|
||||
assert( d.size() > 2 );
|
||||
|
||||
c.clear();
|
||||
typename Container::reference r = *d.begin();
|
||||
c.insert(d.begin(), ++d.begin());
|
||||
BOOST_TEST( &*Container::s_iterator_to(*c.begin()) == &r );
|
||||
BOOST_TEST( &*Container::s_iterator_to(*c.cbegin()) == &r );
|
||||
|
||||
c.clear();
|
||||
c.insert(d.begin(), d.end());
|
||||
|
||||
@@ -259,7 +269,6 @@ void test_common_unordered_and_associative_container(Container & c, Data & d, bo
|
||||
BOOST_TEST( c.equal_range(*da, c.key_comp()).first == c.end() );
|
||||
}
|
||||
|
||||
|
||||
template< class Container, class Data >
|
||||
void test_common_unordered_and_associative_container(Container & c, Data & d)
|
||||
{
|
||||
@@ -267,6 +276,12 @@ void test_common_unordered_and_associative_container(Container & c, Data & d)
|
||||
{
|
||||
assert( d.size() > 2 );
|
||||
|
||||
c.clear();
|
||||
typename Container::reference r = *d.begin();
|
||||
c.insert(d.begin(), ++d.begin());
|
||||
BOOST_TEST( &*c.iterator_to(*c.begin()) == &r );
|
||||
BOOST_TEST( &*c.iterator_to(*c.cbegin()) == &r );
|
||||
|
||||
c.clear();
|
||||
c.insert(d.begin(), d.end());
|
||||
|
||||
@@ -372,6 +387,9 @@ void test_unordered_associative_container_invariants(Container & c, Data & d)
|
||||
size_type bucket_elem = std::distance(c.begin(nb), c.end(nb));
|
||||
BOOST_TEST( bucket_elem == c.bucket_size(nb) );
|
||||
BOOST_TEST( &*c.local_iterator_to(*c.find(*di)) == &*i );
|
||||
BOOST_TEST( &*c.local_iterator_to(*const_cast<const Container &>(c).find(*di)) == &*i );
|
||||
BOOST_TEST( &*Container::s_local_iterator_to(*c.find(*di)) == &*i );
|
||||
BOOST_TEST( &*Container::s_local_iterator_to(*const_cast<const Container &>(c).find(*di)) == &*i );
|
||||
std::pair<const_iterator, const_iterator> er = c.equal_range(*di);
|
||||
size_type cnt = std::distance(er.first, er.second);
|
||||
BOOST_TEST( cnt == c.count(*di));
|
||||
|
Reference in New Issue
Block a user