forked from boostorg/intrusive
Merge branch 'develop'
This commit is contained in:
@@ -1711,7 +1711,8 @@ class bstree_algorithms
|
||||
|
||||
static void vine_to_subtree(const node_ptr & super_root, std::size_t count)
|
||||
{
|
||||
std::size_t leaf_nodes = count + 1 - ((std::size_t) 1 << detail::floor_log2(count + 1));
|
||||
const std::size_t one_szt = 1u;
|
||||
std::size_t leaf_nodes = count + one_szt - std::size_t(one_szt << detail::floor_log2(count + one_szt));
|
||||
compress_subtree(super_root, leaf_nodes); //create deepest leaves
|
||||
std::size_t vine_nodes = count - leaf_nodes;
|
||||
while(vine_nodes > 1){
|
||||
|
@@ -250,33 +250,21 @@ class circular_slist_algorithms
|
||||
{
|
||||
if (other_node == this_node)
|
||||
return;
|
||||
bool this_inited = base_t::inited(this_node);
|
||||
bool other_inited = base_t::inited(other_node);
|
||||
if(this_inited){
|
||||
base_t::init_header(this_node);
|
||||
}
|
||||
if(other_inited){
|
||||
base_t::init_header(other_node);
|
||||
}
|
||||
const node_ptr this_next = NodeTraits::get_next(this_node);
|
||||
const node_ptr other_next = NodeTraits::get_next(other_node);
|
||||
const bool this_null = !this_next;
|
||||
const bool other_null = !other_next;
|
||||
const bool this_empty = this_next == this_node;
|
||||
const bool other_empty = other_next == other_node;
|
||||
|
||||
bool empty1 = base_t::unique(this_node);
|
||||
bool empty2 = base_t::unique(other_node);
|
||||
node_ptr prev_this (get_previous_node(this_node));
|
||||
node_ptr prev_other(get_previous_node(other_node));
|
||||
|
||||
node_ptr this_next (NodeTraits::get_next(this_node));
|
||||
node_ptr other_next(NodeTraits::get_next(other_node));
|
||||
NodeTraits::set_next(this_node, other_next);
|
||||
NodeTraits::set_next(other_node, this_next);
|
||||
NodeTraits::set_next(empty1 ? other_node : prev_this, other_node);
|
||||
NodeTraits::set_next(empty2 ? this_node : prev_other, this_node);
|
||||
|
||||
if(this_inited){
|
||||
base_t::init(other_node);
|
||||
if(!(other_null || other_empty)){
|
||||
NodeTraits::set_next(this_next == other_node ? other_node : get_previous_node(other_node), this_node );
|
||||
}
|
||||
if(other_inited){
|
||||
base_t::init(this_node);
|
||||
if(!(this_null | this_empty)){
|
||||
NodeTraits::set_next(other_next == this_node ? this_node : get_previous_node(this_node), other_node );
|
||||
}
|
||||
NodeTraits::set_next(this_node, other_empty ? this_node : (other_next == this_node ? other_node : other_next) );
|
||||
NodeTraits::set_next(other_node, this_empty ? other_node : (this_next == other_node ? this_node : this_next ) );
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Reverses the order of elements in the list.
|
||||
|
@@ -43,9 +43,6 @@ class common_slist_algorithms
|
||||
return p;
|
||||
}
|
||||
|
||||
static void init_header(const node_ptr & this_node)
|
||||
{ NodeTraits::set_next(this_node, this_node); }
|
||||
|
||||
static void init(const node_ptr & this_node)
|
||||
{ NodeTraits::set_next(this_node, node_ptr()); }
|
||||
|
||||
|
@@ -173,29 +173,30 @@ struct get_slist_impl
|
||||
|
||||
template<class BucketValueTraits, bool IsConst>
|
||||
class hashtable_iterator
|
||||
: public std::iterator
|
||||
< std::forward_iterator_tag
|
||||
, typename BucketValueTraits::real_value_traits::value_type
|
||||
, typename pointer_traits<typename BucketValueTraits::real_value_traits::value_type*>::difference_type
|
||||
, typename detail::add_const_if_c
|
||||
<typename BucketValueTraits::real_value_traits::value_type, IsConst>::type *
|
||||
, typename detail::add_const_if_c
|
||||
<typename BucketValueTraits::real_value_traits::value_type, IsConst>::type &
|
||||
>
|
||||
{
|
||||
typedef typename BucketValueTraits::real_value_traits real_value_traits;
|
||||
typedef typename BucketValueTraits::real_bucket_traits real_bucket_traits;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef std::iterator
|
||||
< std::forward_iterator_tag
|
||||
, typename BucketValueTraits::value_traits::value_type
|
||||
, typename pointer_traits<typename BucketValueTraits::value_traits::value_type*>::difference_type
|
||||
, typename detail::add_const_if_c
|
||||
<typename BucketValueTraits::value_traits::value_type, IsConst>::type *
|
||||
, typename detail::add_const_if_c
|
||||
<typename BucketValueTraits::value_traits::value_type, IsConst>::type &
|
||||
> iterator_traits;
|
||||
|
||||
typedef typename BucketValueTraits::value_traits value_traits;
|
||||
typedef typename BucketValueTraits::bucket_traits bucket_traits;
|
||||
typedef typename value_traits::node_traits node_traits;
|
||||
typedef typename detail::get_slist_impl
|
||||
<typename detail::reduced_slist_node_traits
|
||||
<typename real_value_traits::node_traits>::type
|
||||
<typename value_traits::node_traits>::type
|
||||
>::type slist_impl;
|
||||
typedef typename slist_impl::iterator siterator;
|
||||
typedef typename slist_impl::const_iterator const_siterator;
|
||||
typedef detail::bucket_impl<slist_impl> bucket_type;
|
||||
|
||||
typedef typename pointer_traits
|
||||
<typename real_value_traits::pointer>::template rebind_pointer
|
||||
<typename value_traits::pointer>::template rebind_pointer
|
||||
< const BucketValueTraits >::type const_bucketvaltraits_ptr;
|
||||
typedef typename slist_impl::size_type size_type;
|
||||
|
||||
@@ -207,9 +208,11 @@ class hashtable_iterator
|
||||
}
|
||||
|
||||
public:
|
||||
typedef typename real_value_traits::value_type value_type;
|
||||
typedef typename detail::add_const_if_c<value_type, IsConst>::type *pointer;
|
||||
typedef typename detail::add_const_if_c<value_type, IsConst>::type &reference;
|
||||
typedef typename iterator_traits::difference_type difference_type;
|
||||
typedef typename iterator_traits::value_type value_type;
|
||||
typedef typename iterator_traits::pointer pointer;
|
||||
typedef typename iterator_traits::reference reference;
|
||||
typedef typename iterator_traits::iterator_category iterator_category;
|
||||
|
||||
hashtable_iterator ()
|
||||
{}
|
||||
@@ -250,23 +253,23 @@ class hashtable_iterator
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
return boost::intrusive::detail::to_raw_pointer(this->priv_real_value_traits().to_value_ptr
|
||||
return boost::intrusive::detail::to_raw_pointer(this->priv_value_traits().to_value_ptr
|
||||
(downcast_bucket(slist_it_.pointed_node())));
|
||||
}
|
||||
|
||||
const const_bucketvaltraits_ptr &get_bucket_value_traits() const
|
||||
{ return traitsptr_; }
|
||||
|
||||
const real_value_traits &priv_real_value_traits() const
|
||||
{ return traitsptr_->priv_real_value_traits(); }
|
||||
const value_traits &priv_value_traits() const
|
||||
{ return traitsptr_->priv_value_traits(); }
|
||||
|
||||
const real_bucket_traits &priv_real_bucket_traits() const
|
||||
{ return traitsptr_->priv_real_bucket_traits(); }
|
||||
const bucket_traits &priv_bucket_traits() const
|
||||
{ return traitsptr_->priv_bucket_traits(); }
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
const real_bucket_traits &rbuck_traits = this->priv_real_bucket_traits();
|
||||
const bucket_traits &rbuck_traits = this->priv_bucket_traits();
|
||||
bucket_type* const buckets = boost::intrusive::detail::to_raw_pointer(rbuck_traits.bucket_begin());
|
||||
const size_type buckets_len = rbuck_traits.bucket_count();
|
||||
|
||||
|
@@ -67,7 +67,6 @@ struct list_node_traits
|
||||
// node oriented bidirectional iterator:
|
||||
template<class RealValueTraits, bool IsConst>
|
||||
class list_iterator
|
||||
: public iiterator<RealValueTraits, IsConst, std::bidirectional_iterator_tag>::iterator_base
|
||||
{
|
||||
protected:
|
||||
typedef iiterator
|
||||
@@ -83,9 +82,11 @@ class list_iterator
|
||||
typedef typename types_t::void_pointer void_pointer;
|
||||
|
||||
public:
|
||||
typedef typename types_t::value_type value_type;
|
||||
typedef typename types_t::pointer pointer;
|
||||
typedef typename types_t::reference reference;
|
||||
typedef typename types_t::iterator_traits::difference_type difference_type;
|
||||
typedef typename types_t::iterator_traits::value_type value_type;
|
||||
typedef typename types_t::iterator_traits::pointer pointer;
|
||||
typedef typename types_t::iterator_traits::reference reference;
|
||||
typedef typename types_t::iterator_traits::iterator_category iterator_category;
|
||||
|
||||
typedef typename pointer_traits
|
||||
<void_pointer>::template rebind_pointer
|
||||
|
@@ -56,7 +56,6 @@ struct slist_node_traits
|
||||
// node oriented bidirectional iterator:
|
||||
template<class RealValueTraits, bool IsConst>
|
||||
class slist_iterator
|
||||
: public iiterator<RealValueTraits, IsConst, std::forward_iterator_tag>::iterator_base
|
||||
{
|
||||
protected:
|
||||
typedef iiterator
|
||||
@@ -72,9 +71,11 @@ class slist_iterator
|
||||
typedef typename types_t::void_pointer void_pointer;
|
||||
|
||||
public:
|
||||
typedef typename types_t::value_type value_type;
|
||||
typedef typename types_t::pointer pointer;
|
||||
typedef typename types_t::reference reference;
|
||||
typedef typename types_t::iterator_traits::difference_type difference_type;
|
||||
typedef typename types_t::iterator_traits::value_type value_type;
|
||||
typedef typename types_t::iterator_traits::pointer pointer;
|
||||
typedef typename types_t::iterator_traits::reference reference;
|
||||
typedef typename types_t::iterator_traits::iterator_category iterator_category;
|
||||
|
||||
typedef typename pointer_traits
|
||||
<void_pointer>::template rebind_pointer
|
||||
|
@@ -82,7 +82,6 @@ struct tree_node_traits
|
||||
// node oriented bidirectional iterator:
|
||||
template<class RealValueTraits, bool IsConst>
|
||||
class tree_iterator
|
||||
: public iiterator<RealValueTraits, IsConst, std::bidirectional_iterator_tag>::iterator_base
|
||||
{
|
||||
protected:
|
||||
typedef iiterator< RealValueTraits, IsConst
|
||||
@@ -99,13 +98,14 @@ class tree_iterator
|
||||
typedef typename pointer_traits
|
||||
<void_pointer>::template rebind_pointer
|
||||
<const real_value_traits>::type const_real_value_traits_ptr;
|
||||
typedef bstree_algorithms<node_traits> node_algorithms;
|
||||
|
||||
public:
|
||||
typedef typename types_t::value_type value_type;
|
||||
typedef typename types_t::pointer pointer;
|
||||
typedef typename types_t::reference reference;
|
||||
|
||||
typedef bstree_algorithms<node_traits> node_algorithms;
|
||||
typedef typename types_t::iterator_traits::difference_type difference_type;
|
||||
typedef typename types_t::iterator_traits::value_type value_type;
|
||||
typedef typename types_t::iterator_traits::pointer pointer;
|
||||
typedef typename types_t::iterator_traits::reference reference;
|
||||
typedef typename types_t::iterator_traits::iterator_category iterator_category;
|
||||
|
||||
tree_iterator()
|
||||
{}
|
||||
|
@@ -89,8 +89,6 @@ struct TRAITS_PREFIX##_bool_is_true\
|
||||
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_value_traits, external_value_traits)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_bucket_traits, external_bucket_traits)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(resizable, resizable)
|
||||
|
||||
template <class T>
|
||||
@@ -163,8 +161,8 @@ struct size_holder
|
||||
SizeType size_;
|
||||
};
|
||||
|
||||
template<class SizeType>
|
||||
struct size_holder<false, SizeType>
|
||||
template<class SizeType, class Tag>
|
||||
struct size_holder<false, SizeType, Tag>
|
||||
{
|
||||
static const bool constant_time_size = false;
|
||||
typedef SizeType size_type;
|
||||
@@ -364,25 +362,180 @@ template<class Hook>
|
||||
void destructor_impl(Hook &, detail::link_dispatch<normal_link>)
|
||||
{}
|
||||
|
||||
//This function uses binary search to discover the
|
||||
//highest set bit of the integer
|
||||
inline std::size_t floor_log2 (std::size_t x)
|
||||
{
|
||||
const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
|
||||
const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
|
||||
BOOST_STATIC_ASSERT(Size_t_Bits_Power_2);
|
||||
///////////////////////////
|
||||
// floor_log2 Dispatcher
|
||||
////////////////////////////
|
||||
|
||||
std::size_t n = x;
|
||||
std::size_t log2 = 0;
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||||
|
||||
for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
|
||||
std::size_t tmp = n >> shift;
|
||||
if (tmp)
|
||||
log2 += shift, n = tmp;
|
||||
}}} //namespace boost::intrusive::detail
|
||||
|
||||
//Use _BitScanReverseXX intrinsics
|
||||
|
||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(_M_IA64) //64 bit target
|
||||
#define BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT
|
||||
#endif
|
||||
|
||||
#ifndef __INTRIN_H_ // Avoid including any windows system header
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT) //64 bit target
|
||||
unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask);
|
||||
#pragma intrinsic(_BitScanReverse64)
|
||||
#else //32 bit target
|
||||
unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
|
||||
#pragma intrinsic(_BitScanReverse)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
#endif // __INTRIN_H_
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT
|
||||
#define BOOST_INTRUSIVE_BSR_INTRINSIC _BitScanReverse64
|
||||
#undef BOOST_INTRUSIVE_BSR_INTRINSIC_64_BIT
|
||||
#else
|
||||
#define BOOST_INTRUSIVE_BSR_INTRINSIC _BitScanReverse
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
namespace detail {
|
||||
|
||||
inline std::size_t floor_log2 (std::size_t x)
|
||||
{
|
||||
unsigned long log2;
|
||||
BOOST_INTRUSIVE_BSR_INTRINSIC( &log2, (unsigned long)x );
|
||||
return log2;
|
||||
}
|
||||
|
||||
return log2;
|
||||
}
|
||||
#undef BOOST_INTRUSIVE_BSR_INTRINSIC
|
||||
|
||||
#elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) //GCC >=3.4
|
||||
|
||||
//Compile-time error in case of missing specialization
|
||||
template<class Uint>
|
||||
struct builtin_clz_dispatch;
|
||||
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
template<>
|
||||
struct builtin_clz_dispatch<unsigned long long>
|
||||
{
|
||||
static const unsigned long long call(unsigned long long n)
|
||||
{ return __builtin_clzll(n); }
|
||||
};
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct builtin_clz_dispatch<unsigned long>
|
||||
{
|
||||
static const unsigned long call(unsigned long n)
|
||||
{ return __builtin_clzl(n); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct builtin_clz_dispatch<unsigned int>
|
||||
{
|
||||
static const unsigned int call(unsigned int n)
|
||||
{ return __builtin_clz(n); }
|
||||
};
|
||||
|
||||
inline std::size_t floor_log2(std::size_t n)
|
||||
{
|
||||
return sizeof(std::size_t)*CHAR_BIT - std::size_t(1) - builtin_clz_dispatch<std::size_t>::call(n);
|
||||
}
|
||||
|
||||
#else //Portable methods
|
||||
|
||||
////////////////////////////
|
||||
// Generic method
|
||||
////////////////////////////
|
||||
|
||||
inline std::size_t floor_log2_get_shift(std::size_t n, true_ )//power of two size_t
|
||||
{ return n >> 1; }
|
||||
|
||||
inline std::size_t floor_log2_get_shift(std::size_t n, false_ )//non-power of two size_t
|
||||
{ return (n >> 1) + ((n & 1u) & (n != 1)); }
|
||||
|
||||
template<std::size_t N>
|
||||
inline std::size_t floor_log2 (std::size_t x, integer<std::size_t, N>)
|
||||
{
|
||||
const std::size_t Bits = N;
|
||||
const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
|
||||
|
||||
std::size_t n = x;
|
||||
std::size_t log2 = 0;
|
||||
|
||||
std::size_t remaining_bits = Bits;
|
||||
std::size_t shift = floor_log2_get_shift(remaining_bits, bool_<Size_t_Bits_Power_2>());
|
||||
while(shift){
|
||||
std::size_t tmp = n >> shift;
|
||||
if (tmp){
|
||||
log2 += shift, n = tmp;
|
||||
}
|
||||
shift = floor_log2_get_shift(shift, bool_<Size_t_Bits_Power_2>());
|
||||
}
|
||||
|
||||
return log2;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// DeBruijn method
|
||||
////////////////////////////
|
||||
|
||||
//Taken from:
|
||||
//http://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers
|
||||
//Thanks to Desmond Hume
|
||||
|
||||
inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 32>)
|
||||
{
|
||||
static const int MultiplyDeBruijnBitPosition[32] =
|
||||
{
|
||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
||||
};
|
||||
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
|
||||
return MultiplyDeBruijnBitPosition[(std::size_t)(v * 0x07C4ACDDU) >> 27];
|
||||
}
|
||||
|
||||
inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 64>)
|
||||
{
|
||||
static const std::size_t MultiplyDeBruijnBitPosition[64] = {
|
||||
63, 0, 58, 1, 59, 47, 53, 2,
|
||||
60, 39, 48, 27, 54, 33, 42, 3,
|
||||
61, 51, 37, 40, 49, 18, 28, 20,
|
||||
55, 30, 34, 11, 43, 14, 22, 4,
|
||||
62, 57, 46, 52, 38, 26, 32, 41,
|
||||
50, 36, 17, 19, 29, 10, 13, 21,
|
||||
56, 45, 25, 31, 35, 16, 9, 12,
|
||||
44, 24, 15, 8, 23, 7, 6, 5};
|
||||
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v |= v >> 32;
|
||||
return MultiplyDeBruijnBitPosition[((std::size_t)((v - (v >> 1))*0x07EDD5E59A4E28C2ULL)) >> 58];
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t floor_log2 (std::size_t x)
|
||||
{
|
||||
const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
|
||||
return floor_log2(x, integer<std::size_t, Bits>());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//Thanks to Laurent de Soras in
|
||||
//http://www.flipcode.com/archives/Fast_log_Function.shtml
|
||||
@@ -404,13 +557,13 @@ inline float fast_log2 (float val)
|
||||
//1+log2(m), m ranging from 1 to 2
|
||||
//3rd degree polynomial keeping first derivate continuity.
|
||||
//For less precision the line can be commented out
|
||||
val = ((-1.0f/3.f) * val + 2.f) * val - (2.0f/3.f);
|
||||
val = ((-1.f/3.f) * val + 2.f) * val - (2.f/3.f);
|
||||
return (val + log_2);
|
||||
}
|
||||
|
||||
inline std::size_t ceil_log2 (std::size_t x)
|
||||
{
|
||||
return ((x & (x-1))!= 0) + floor_log2(x);
|
||||
return static_cast<std::size_t>((x & (x-1)) != 0) + floor_log2(x);
|
||||
}
|
||||
|
||||
template<class SizeType, std::size_t N>
|
||||
@@ -980,7 +1133,7 @@ struct iiterator
|
||||
, difference_type
|
||||
, pointer
|
||||
, reference
|
||||
> iterator_base;
|
||||
> iterator_traits;
|
||||
static const bool stateful_value_traits =
|
||||
detail::is_stateful_value_traits<real_value_traits>::value;
|
||||
};
|
||||
|
@@ -2685,15 +2685,16 @@ class hashtable_impl
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
void priv_clear_buckets(bucket_ptr buckets_ptr, size_type bucket_cnt)
|
||||
void priv_clear_buckets(const bucket_ptr buckets_ptr, const size_type bucket_cnt)
|
||||
{
|
||||
for(; bucket_cnt--; ++buckets_ptr){
|
||||
bucket_ptr buckets_it = buckets_ptr;
|
||||
for(size_type bucket_i = 0; bucket_i != bucket_cnt; ++buckets_it, ++bucket_i){
|
||||
if(safemode_or_autounlink){
|
||||
bucket_plus_vtraits_t::priv_clear_group_nodes(*buckets_ptr, optimize_multikey_t());
|
||||
buckets_ptr->clear_and_dispose(detail::init_disposer<node_algorithms>());
|
||||
bucket_plus_vtraits_t::priv_clear_group_nodes(*buckets_it, optimize_multikey_t());
|
||||
buckets_it->clear_and_dispose(detail::init_disposer<node_algorithms>());
|
||||
}
|
||||
else{
|
||||
buckets_ptr->clear();
|
||||
buckets_it->clear();
|
||||
}
|
||||
}
|
||||
this->priv_initialize_cache();
|
||||
|
@@ -158,10 +158,10 @@ struct pointer_traits
|
||||
|
||||
//priv_pointer_to
|
||||
static pointer priv_pointer_to(boost::true_type, typename boost::intrusive::detail::unvoid<element_type>::type& r)
|
||||
{ return Ptr::pointer_to(r); }
|
||||
{ return Ptr::pointer_to(r); }
|
||||
|
||||
static pointer priv_pointer_to(boost::false_type, typename boost::intrusive::detail::unvoid<element_type>::type& r)
|
||||
{ return pointer(boost::intrusive::detail::addressof(r)); }
|
||||
{ return pointer(boost::intrusive::detail::addressof(r)); }
|
||||
|
||||
//priv_static_cast_from
|
||||
template<class UPtr>
|
||||
@@ -188,7 +188,15 @@ struct pointer_traits
|
||||
|
||||
template<class UPtr>
|
||||
static pointer priv_dynamic_cast_from(boost::false_type, const UPtr &uptr)
|
||||
{ return pointer_to(*dynamic_cast<element_type*>(&*uptr)); }
|
||||
{
|
||||
element_type *p = dynamic_cast<element_type*>(&*uptr);
|
||||
if(!p){
|
||||
return pointer();
|
||||
}
|
||||
else{
|
||||
return pointer_to(*p);
|
||||
}
|
||||
}
|
||||
///@endcond
|
||||
};
|
||||
|
||||
|
@@ -52,8 +52,8 @@ struct testvalue
|
||||
// have to be handled appropriately when copied:
|
||||
testvalue & operator= (const testvalue& src)
|
||||
{
|
||||
Hooks::base_hook_type::operator=(src);
|
||||
Hooks::auto_base_hook_type::operator=(src);
|
||||
Hooks::base_hook_type::operator=(static_cast<const typename Hooks::base_hook_type&>(src));
|
||||
Hooks::auto_base_hook_type::operator=(static_cast<const typename Hooks::auto_base_hook_type&>(src));
|
||||
this->node_ = src.node_;
|
||||
this->auto_node_ = src.auto_node_;
|
||||
value_ = src.value_;
|
||||
@@ -62,8 +62,8 @@ struct testvalue
|
||||
|
||||
void swap_nodes(testvalue &other)
|
||||
{
|
||||
Hooks::base_hook_type::swap_nodes(other);
|
||||
Hooks::auto_base_hook_type::swap_nodes(other);
|
||||
Hooks::base_hook_type::swap_nodes(static_cast<typename Hooks::base_hook_type&>(other));
|
||||
Hooks::auto_base_hook_type::swap_nodes(static_cast<typename Hooks::auto_base_hook_type&>(other));
|
||||
node_.swap_nodes(other.node_);
|
||||
auto_node_.swap_nodes(other.auto_node_);
|
||||
}
|
||||
|
@@ -456,23 +456,32 @@ void test_slist<ValueTraits, Linear, CacheLast>
|
||||
}
|
||||
if(!list_type::linear)
|
||||
{
|
||||
list_type testlist1 (&values[0], &values[1]);
|
||||
|
||||
list_type testlist1 (&values[0], &values[0]+1);
|
||||
if(testlist1.size() != 1){
|
||||
abort();
|
||||
}
|
||||
{ int init_values [] = { 1 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
|
||||
|
||||
values[1].swap_nodes(values[2]);
|
||||
|
||||
BOOST_TEST(testlist1.size() == 1);
|
||||
BOOST_TEST(!values[1].is_linked());
|
||||
BOOST_TEST(!values[2].is_linked());
|
||||
{ int init_values [] = { 1 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
|
||||
|
||||
values[0].swap_nodes(values[2]);
|
||||
|
||||
BOOST_TEST(testlist1.size() == 1);
|
||||
BOOST_TEST(values[2].is_linked());
|
||||
BOOST_TEST(!values[0].is_linked());
|
||||
{ int init_values [] = { 3 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
|
||||
|
||||
values[0].swap_nodes(values[2]);
|
||||
|
||||
BOOST_TEST(testlist1.size() == 1);
|
||||
BOOST_TEST(!values[2].is_linked());
|
||||
BOOST_TEST(values[0].is_linked());
|
||||
{ int init_values [] = { 1 };
|
||||
TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
|
||||
}
|
||||
@@ -730,207 +739,3 @@ int main(int, char* [])
|
||||
return boost::report_errors();
|
||||
}
|
||||
#include <boost/intrusive/detail/config_end.hpp>
|
||||
|
||||
/*
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
|
||||
namespace intrusive = boost::intrusive;
|
||||
|
||||
class object : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
int o;
|
||||
object()
|
||||
{
|
||||
}
|
||||
virtual ~object()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class signal : virtual public object
|
||||
{
|
||||
public:
|
||||
signal()
|
||||
{
|
||||
}
|
||||
virtual ~signal()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class set_item : public signal
|
||||
{
|
||||
public:
|
||||
set_item()
|
||||
{
|
||||
}
|
||||
virtual ~set_item()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual const std::string& get_buffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
typedef intrusive::set_member_hook<
|
||||
intrusive::link_mode<intrusive::auto_unlink>
|
||||
> hook;
|
||||
hook m_hook;
|
||||
|
||||
std::string m_buffer;
|
||||
};
|
||||
|
||||
|
||||
template <class T, class M, M (T::*V)>
|
||||
struct member_comparator
|
||||
{
|
||||
bool operator()(const T& t1, const T& t2) const
|
||||
{
|
||||
return (t1.*V) < (t2.*V);
|
||||
}
|
||||
bool operator()(const M& m, const T& t) const
|
||||
{
|
||||
return m < (t.*V);
|
||||
}
|
||||
bool operator()(const T& t, const M& m) const
|
||||
{
|
||||
return (t.*V) < m;
|
||||
}
|
||||
};
|
||||
|
||||
class kk{ int a; float f; };
|
||||
|
||||
class list_item : public kk, virtual public object
|
||||
{
|
||||
public:
|
||||
list_item()
|
||||
{
|
||||
}
|
||||
virtual ~list_item()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void f()
|
||||
{
|
||||
}
|
||||
|
||||
typedef intrusive::list_member_hook<
|
||||
intrusive::link_mode<intrusive::auto_unlink>
|
||||
> hook;
|
||||
hook m_hook;
|
||||
};
|
||||
|
||||
set_item srec;
|
||||
list_item lrec;
|
||||
|
||||
const set_item::hook set_item::* sptr_to_member = &set_item::m_hook;
|
||||
const list_item::hook list_item::* lptr_to_member = &list_item::m_hook;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int a = sizeof(sptr_to_member);
|
||||
int b = sizeof(lptr_to_member);
|
||||
const std::type_info &ta = typeid(set_item);
|
||||
const std::type_info &tb = typeid(list_item);
|
||||
|
||||
const set_item::hook &sh = srec.*sptr_to_member;
|
||||
const list_item::hook &l2 = lrec.*lptr_to_member;
|
||||
|
||||
{
|
||||
typedef member_comparator<
|
||||
set_item,
|
||||
std::string,
|
||||
&set_item::m_buffer
|
||||
> set_item_comparator;
|
||||
|
||||
typedef intrusive::set<
|
||||
set_item,
|
||||
intrusive::compare<set_item_comparator>,
|
||||
intrusive::member_hook<
|
||||
set_item,
|
||||
set_item::hook,
|
||||
&set_item::m_hook
|
||||
>,
|
||||
intrusive::constant_time_size<false>
|
||||
> set_items
|
||||
;
|
||||
|
||||
union
|
||||
{
|
||||
int as_int[2];
|
||||
const set_item::hook set_item::* ptr_to_member;
|
||||
}
|
||||
sss;
|
||||
sss.ptr_to_member = &set_item::m_hook;
|
||||
|
||||
std::cout << "set offsets: " << sss.as_int[0] << ":" << sss.as_int[1] << " and " << offsetof(set_item,m_hook) << std::endl;
|
||||
|
||||
set_items rr;
|
||||
|
||||
std::string key = "123";
|
||||
set_items::insert_commit_data icd;
|
||||
std::pair<set_items::iterator,bool> ir = rr.insert_check(
|
||||
key,
|
||||
set_item_comparator(),
|
||||
icd
|
||||
);
|
||||
|
||||
if ( !ir.second )
|
||||
{
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
set_item rec;
|
||||
rec.m_buffer = key;
|
||||
set_items::iterator i = rr.insert_commit( rec, icd );
|
||||
|
||||
set_item* rrr = &(*i);
|
||||
|
||||
std::cout << "set pointers: " << ((void*)rrr) << " and " << ((void*)&rec) << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
typedef intrusive::list<
|
||||
list_item,
|
||||
intrusive::member_hook<
|
||||
list_item,
|
||||
list_item::hook,
|
||||
&list_item::m_hook
|
||||
>,
|
||||
intrusive::constant_time_size<false>
|
||||
> list_items
|
||||
;
|
||||
|
||||
union
|
||||
{
|
||||
int as_int[2];
|
||||
const list_item::hook list_item::* ptr_to_member;
|
||||
}
|
||||
sss;
|
||||
sss.ptr_to_member = &list_item::m_hook;
|
||||
|
||||
std::cout << "list offsets: " << sss.as_int[0] << ":" << sss.as_int[1] << " and " << offsetof(list_item,m_hook) << std::endl;
|
||||
|
||||
list_items rr;
|
||||
|
||||
list_item rec;
|
||||
const list_item::hook &h = rec.*sss.ptr_to_member;
|
||||
rr.push_back( rec );
|
||||
|
||||
list_item* rrr = &rr.front();
|
||||
|
||||
std::cout << "list pointers: " << ((void*)rrr) << " and " << ((void*)&rec) << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
@@ -261,38 +261,6 @@ inline void swap (smart_ptr<T> &pt,
|
||||
pt2 = ptr;
|
||||
}
|
||||
|
||||
//!Simulation of static_cast between pointers. Never throws.
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>
|
||||
static_pointer_cast(const smart_ptr<U> & r)
|
||||
{
|
||||
return smart_ptr<T>(r, detail::static_cast_tag());
|
||||
}
|
||||
|
||||
//!Simulation of const_cast between pointers. Never throws.
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>const_pointer_cast(smart_ptr<U> const & r)
|
||||
{
|
||||
return smart_ptr<T>(r, detail::const_cast_tag());
|
||||
}
|
||||
|
||||
//!Simulation of dynamic_cast between pointers. Never throws.
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>
|
||||
dynamic_pointer_cast(smart_ptr<U> const & r)
|
||||
{
|
||||
return smart_ptr<T>
|
||||
(r, detail::dynamic_cast_tag());
|
||||
}
|
||||
|
||||
//!Simulation of reinterpret_cast between pointers. Never throws.
|
||||
template<class T, class U>
|
||||
inline smart_ptr<T>
|
||||
reinterpret_pointer_cast(smart_ptr<U> const & r)
|
||||
{
|
||||
return smart_ptr<T>(r, detail::reinterpret_cast_tag());
|
||||
}
|
||||
|
||||
} //namespace intrusive {
|
||||
} //namespace boost {
|
||||
|
||||
|
@@ -13,14 +13,33 @@
|
||||
#ifndef BOOST_INTRUSIVE_TEST_TEST_MACROS_HPP
|
||||
#define BOOST_INTRUSIVE_TEST_TEST_MACROS_HPP
|
||||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
|
||||
template<class It1, class It2>
|
||||
bool test_equal(It1 f1, It1 l1, It2 f2)
|
||||
{
|
||||
while(f1 != l1){
|
||||
if(*f1 != *f2){
|
||||
return false;
|
||||
}
|
||||
++f1;
|
||||
++f2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TEST_INTRUSIVE_SEQUENCE( INTVALUES, ITERATOR )\
|
||||
{ \
|
||||
BOOST_TEST (std::equal(&INTVALUES[0], &INTVALUES[0] + sizeof(INTVALUES)/sizeof(INTVALUES[0]), ITERATOR) ); \
|
||||
BOOST_TEST (boost::intrusive::test_equal(&INTVALUES[0], &INTVALUES[0] + sizeof(INTVALUES)/sizeof(INTVALUES[0]), ITERATOR) ); \
|
||||
}
|
||||
|
||||
#define TEST_INTRUSIVE_SEQUENCE_EXPECTED( EXPECTEDVECTOR, ITERATOR )\
|
||||
{ \
|
||||
BOOST_TEST (std::equal(EXPECTEDVECTOR.begin(), EXPECTEDVECTOR.end(), ITERATOR) ); \
|
||||
BOOST_TEST (boost::intrusive::test_equal(EXPECTEDVECTOR.begin(), EXPECTEDVECTOR.end(), ITERATOR) ); \
|
||||
}
|
||||
|
||||
} //namespace boost{
|
||||
} //namespace intrusive{
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user