Container, Interprocess, Intrusive, Move merge for 1.54

[SVN r84341]
This commit is contained in:
Ion Gaztañaga
2013-05-18 10:40:55 +00:00
parent 8b917e96a7
commit a479114dc9
7 changed files with 66 additions and 26 deletions

View File

@@ -16,9 +16,9 @@
#include <cstddef> #include <cstddef>
#if defined(BOOST_MSVC) || ((defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && defined(BOOST_INTEL)) #if defined(BOOST_MSVC) || ((defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && defined(BOOST_INTEL))
#define BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER
#define BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER #include <boost/cstdint.hpp>
#include <boost/cstdint.hpp> #include <boost/static_assert.hpp>
#endif #endif
namespace boost { namespace boost {
@@ -29,7 +29,7 @@ template<class Parent, class Member>
inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member) inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member)
{ {
//The implementation of a pointer to member is compiler dependent. //The implementation of a pointer to member is compiler dependent.
#if defined(BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER) #if defined(BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER)
//msvc compliant compilers use their the first 32 bits as offset (even in 64 bit mode) //msvc compliant compilers use their the first 32 bits as offset (even in 64 bit mode)
union caster_union union caster_union
{ {
@@ -37,6 +37,10 @@ inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_t
boost::int32_t offset; boost::int32_t offset;
} caster; } caster;
caster.ptr_to_member = ptr_to_member; caster.ptr_to_member = ptr_to_member;
//MSVC ABI can use up to 3 int32 to represent pointer to member data
//with virtual base classes, in those cases there is no simple to
//obtain the address of parent. So static assert to avoid runtime errors
BOOST_STATIC_ASSERT( sizeof(caster) == sizeof(boost::int32_t) );
return std::ptrdiff_t(caster.offset); return std::ptrdiff_t(caster.offset);
//This works with gcc, msvc, ac++, ibmcpp //This works with gcc, msvc, ac++, ibmcpp
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \ #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \
@@ -84,8 +88,8 @@ inline const Parent *parent_from_member(const Member *member, const Member Paren
} //namespace intrusive { } //namespace intrusive {
} //namespace boost { } //namespace boost {
#ifdef BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER #ifdef BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER
#undef BOOST_INTRUSIVE_MSVC_COMPLIANT_PTR_TO_MEMBER #undef BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER
#endif #endif
#include <boost/intrusive/detail/config_end.hpp> #include <boost/intrusive/detail/config_end.hpp>

View File

@@ -28,6 +28,7 @@
#include <iterator> #include <iterator>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/detail/no_exceptions_support.hpp>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
@@ -131,6 +132,12 @@ struct size_holder
void increment() void increment()
{ ++size_; } { ++size_; }
void increase(SizeType n)
{ size_ += n; }
void decrease(SizeType n)
{ size_ -= n; }
SizeType size_; SizeType size_;
}; };
@@ -151,6 +158,12 @@ struct size_holder<false, SizeType>
void increment() void increment()
{} {}
void increase(SizeType)
{}
void decrease(SizeType)
{}
}; };
template<class KeyValueCompare, class Container> template<class KeyValueCompare, class Container>
@@ -692,19 +705,20 @@ class array_initializer
{ {
char *init_buf = (char*)rawbuf; char *init_buf = (char*)rawbuf;
std::size_t i = 0; std::size_t i = 0;
try{ BOOST_TRY{
for(; i != N; ++i){ for(; i != N; ++i){
new(init_buf)T(init); new(init_buf)T(init);
init_buf += sizeof(T); init_buf += sizeof(T);
} }
} }
catch(...){ BOOST_CATCH(...){
while(i--){ while(i--){
init_buf -= sizeof(T); init_buf -= sizeof(T);
((T*)init_buf)->~T(); ((T*)init_buf)->~T();
} }
throw; BOOST_RETHROW;
} }
BOOST_CATCH_END
} }
operator T* () operator T* ()

View File

@@ -645,7 +645,7 @@ class list_impl
} }
else{ else{
if(constant_time_size){ if(constant_time_size){
this->priv_size_traits().set_size(this->priv_size_traits().get_size() - n); this->priv_size_traits().decrease(n);
} }
node_algorithms::unlink(b.pointed_node(), e.pointed_node()); node_algorithms::unlink(b.pointed_node(), e.pointed_node());
return e.unconst(); return e.unconst();
@@ -886,11 +886,11 @@ class list_impl
void splice(const_iterator p, list_impl& x) void splice(const_iterator p, list_impl& x)
{ {
if(!x.empty()){ if(!x.empty()){
size_traits &thist = this->priv_size_traits();
size_traits &xt = x.priv_size_traits();
node_algorithms::transfer node_algorithms::transfer
(p.pointed_node(), x.begin().pointed_node(), x.end().pointed_node()); (p.pointed_node(), x.begin().pointed_node(), x.end().pointed_node());
thist.set_size(thist.get_size() + xt.get_size()); size_traits &thist = this->priv_size_traits();
size_traits &xt = x.priv_size_traits();
thist.increase(xt.get_size());
xt.set_size(size_type(0)); xt.set_size(size_type(0));
} }
} }
@@ -953,12 +953,12 @@ class list_impl
{ {
if(n){ if(n){
if(constant_time_size){ if(constant_time_size){
size_traits &thist = this->priv_size_traits();
size_traits &xt = x.priv_size_traits();
BOOST_INTRUSIVE_INVARIANT_ASSERT(n == std::distance(f, e)); BOOST_INTRUSIVE_INVARIANT_ASSERT(n == std::distance(f, e));
node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node()); node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node());
thist.set_size(thist.get_size() + n); size_traits &thist = this->priv_size_traits();
xt.set_size(xt.get_size() - n); size_traits &xt = x.priv_size_traits();
thist.increase(n);
xt.decrease(n);
} }
else{ else{
node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node()); node_algorithms::transfer(p.pointed_node(), f.pointed_node(), e.pointed_node());

View File

@@ -33,6 +33,8 @@ namespace detail{
struct default_hook_tag{}; struct default_hook_tag{};
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \ #define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \
struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\ struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\
{\ {\
@@ -51,6 +53,8 @@ BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bs_set_hook);
#undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION #undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
template <class ValueTraits> template <class ValueTraits>
struct eval_value_traits struct eval_value_traits
{ {

View File

@@ -47,7 +47,11 @@ struct max_pointer_plus_bits<void*, Alignment>
//!has_pointer_plus_bits<>::value is non-zero can make use of these //!has_pointer_plus_bits<>::value is non-zero can make use of these
//!operations to embed the bits in the pointer. //!operations to embed the bits in the pointer.
template<class Pointer, std::size_t NumBits> template<class Pointer, std::size_t NumBits>
struct pointer_plus_bits; struct pointer_plus_bits
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
{}
#endif
;
//!This is the specialization to embed extra bits of information //!This is the specialization to embed extra bits of information
//!in a raw pointer. The extra bits are stored in the lower bits of the pointer. //!in a raw pointer. The extra bits are stored in the lower bits of the pointer.

View File

@@ -819,8 +819,23 @@ class slist_impl
template<class Iterator> template<class Iterator>
void insert_after(const_iterator prev_p, Iterator f, Iterator l) void insert_after(const_iterator prev_p, Iterator f, Iterator l)
{ {
for (; f != l; ++f) //Insert first nodes avoiding cache and size checks
prev_p = this->insert_after(prev_p, *f); size_type count = 0;
node_ptr prev_n(prev_p.pointed_node());
for (; f != l; ++f, ++count){
const node_ptr n = get_real_value_traits().to_node_ptr(*f);
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
node_algorithms::link_after(prev_n, n);
prev_n = n;
}
//Now fix special cases if needed
if(cache_last && (this->get_last_node() == prev_p.pointed_node())){
this->set_last_node(prev_n);
}
if(constant_time_size){
this->priv_size_traits().increase(count);
}
} }
//! <b>Requires</b>: value must be an lvalue and p must point to an element //! <b>Requires</b>: value must be an lvalue and p must point to an element
@@ -932,7 +947,7 @@ class slist_impl
} }
node_algorithms::unlink_after(bfp, lp); node_algorithms::unlink_after(bfp, lp);
if(constant_time_size){ if(constant_time_size){
this->priv_size_traits().set_size(this->priv_size_traits().get_size() - n); this->priv_size_traits().decrease(n);
} }
return l.unconst(); return l.unconst();
} }
@@ -1209,7 +1224,7 @@ class slist_impl
} }
} }
node_algorithms::transfer_after( prev_n, x.before_begin().pointed_node(), last_x_n); node_algorithms::transfer_after( prev_n, x.before_begin().pointed_node(), last_x_n);
this->priv_size_traits().set_size(this->priv_size_traits().get_size() + x.priv_size_traits().get_size()); this->priv_size_traits().increase(x.priv_size_traits().get_size());
x.priv_size_traits().set_size(size_type(0)); x.priv_size_traits().set_size(size_type(0));
if(l) *l = last_x; if(l) *l = last_x;
} }
@@ -1278,8 +1293,8 @@ class slist_impl
this->priv_splice_after this->priv_splice_after
(prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node()); (prev_pos.pointed_node(), x, before_f.pointed_node(), before_l.pointed_node());
if(constant_time_size){ if(constant_time_size){
this->priv_size_traits().set_size(this->priv_size_traits().get_size() + n); this->priv_size_traits().increase(n);
x.priv_size_traits().set_size(x.priv_size_traits().get_size() - n); x.priv_size_traits().decrease(n);
} }
} }
@@ -1834,7 +1849,7 @@ class slist_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(size_type(std::distance(iterator(f, this), iterator(before_l, this)))+1 == n); BOOST_INTRUSIVE_INVARIANT_ASSERT(size_type(std::distance(iterator(f, this), iterator(before_l, this)))+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){
this->priv_size_traits().set_size(this->priv_size_traits().get_size() + n); this->priv_size_traits().increase(n);
} }
} }
} }

View File

@@ -389,7 +389,6 @@ class treap_algorithms
{ {
rebalance_for_erasure(header, z, pcomp); rebalance_for_erasure(header, z, pcomp);
tree_algorithms::erase(header, z); tree_algorithms::erase(header, z);
// assert(check_invariant(header, pcomp));
return z; return z;
} }