Skip to content

Commit

Permalink
Merge branch 'think-cell-explicit_ctor_and_32_64_sharing' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
igaztanaga committed Jan 19, 2017
2 parents 945eb1d + d978830 commit acce62f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 70 deletions.
24 changes: 12 additions & 12 deletions include/boost/interprocess/detail/utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,29 +156,29 @@ BOOST_INTERPROCESS_FORCEINLINE bool size_overflows(SizeType count)
return multiplication_overflows(SizeType(SztSizeOfType), count);
}

template<class RawPointer>
class pointer_uintptr_caster;
template<class RawPointer, class OffsetType>
class pointer_offset_caster;

template<class T>
class pointer_uintptr_caster<T*>
template<class T, class OffsetType>
class pointer_offset_caster<T*, OffsetType>
{
public:
BOOST_INTERPROCESS_FORCEINLINE explicit pointer_uintptr_caster(uintptr_t sz)
: m_uintptr(sz)
BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(OffsetType offset)
: m_offset(offset)
{}

BOOST_INTERPROCESS_FORCEINLINE explicit pointer_uintptr_caster(const volatile T *p)
: m_uintptr(reinterpret_cast<uintptr_t>(p))
BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(const volatile T *p)
: m_offset(reinterpret_cast<OffsetType>(p))
{}

BOOST_INTERPROCESS_FORCEINLINE uintptr_t uintptr() const
{ return m_uintptr; }
BOOST_INTERPROCESS_FORCEINLINE OffsetType offset() const
{ return m_offset; }

BOOST_INTERPROCESS_FORCEINLINE T* pointer() const
{ return reinterpret_cast<T*>(m_uintptr); }
{ return reinterpret_cast<T*>(m_offset); }

private:
uintptr_t m_uintptr;
OffsetType m_offset;
};


Expand Down
122 changes: 64 additions & 58 deletions include/boost/interprocess/offset_ptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <boost/interprocess/detail/workaround.hpp>

#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_constructible.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_unsigned.hpp>

#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/detail/utilities.hpp>
Expand Down Expand Up @@ -55,6 +58,7 @@ namespace ipcdetail {
union offset_ptr_internal
{
BOOST_STATIC_ASSERT(sizeof(OffsetType) >= sizeof(uintptr_t));
BOOST_STATIC_ASSERT(boost::is_integral<OffsetType>::value && boost::is_unsigned<OffsetType>::value);

explicit offset_ptr_internal(OffsetType off)
: m_offset(off)
Expand All @@ -81,20 +85,21 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR
BOOST_INTERPROCESS_FORCEINLINE void * offset_ptr_to_raw_pointer(const volatile void *this_ptr, uintptr_t offset)
template <class OffsetType>
BOOST_INTERPROCESS_FORCEINLINE void * offset_ptr_to_raw_pointer(const volatile void *this_ptr, OffsetType offset)
{
typedef pointer_uintptr_caster<void*> caster_t;
typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR
if(offset == 1){
return 0;
}
else{
return caster_t(caster_t(this_ptr).uintptr() + offset).pointer();
return caster_t(caster_t(this_ptr).offset() + offset).pointer();
}
#else
uintptr_t mask = offset == 1;
OffsetType mask = offset == 1;
--mask;
uintptr_t target_offset = caster_t(this_ptr).uintptr() + offset;
OffsetType target_offset = caster_t(this_ptr).offset() + offset;
target_offset &= mask;
return caster_t(target_offset).pointer();
#endif
Expand All @@ -106,27 +111,28 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF
BOOST_INTERPROCESS_FORCEINLINE uintptr_t offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr)
template<class OffsetType>
BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr)
{
typedef pointer_uintptr_caster<void*> caster_t;
typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF
//offset == 1 && ptr != 0 is not legal for this pointer
if(!ptr){
return 1;
}
else{
uintptr_t offset = caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr();
OffsetType offset = caster_t(ptr).offset()- caster_t(this_ptr).offset();
BOOST_ASSERT(offset != 1);
return offset;
}
#else
//const uintptr_t other = -uintptr_t(ptr != 0);
//const uintptr_t offset = (caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr()) & other;
//return offset + uintptr_t(!other);
//const OffsetType other = -OffsetType(ptr != 0);
//const OffsetType offset = (caster_t(ptr).offset() - caster_t(this_ptr).offset()) & other;
//return offset + OffsetType(!other);
//
uintptr_t offset = caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr();
OffsetType offset = caster_t(ptr).offset() - caster_t(this_ptr).offset();
--offset;
uintptr_t mask = uintptr_t(ptr == 0);
OffsetType mask = ptr == 0;
--mask;
offset &= mask;
return ++offset;
Expand All @@ -139,28 +145,29 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF_FROM_OTHER
BOOST_INTERPROCESS_FORCEINLINE uintptr_t offset_ptr_to_offset_from_other
(const volatile void *this_ptr, const volatile void *other_ptr, uintptr_t other_offset)
template<class OffsetType>
BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset_from_other
(const volatile void *this_ptr, const volatile void *other_ptr, OffsetType other_offset)
{
typedef pointer_uintptr_caster<void*> caster_t;
typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF_FROM_OTHER
if(other_offset == 1){
return 1;
}
else{
uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr() + other_offset;
OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset() + other_offset;
BOOST_ASSERT(offset != 1);
return offset;
}
#else
uintptr_t mask = other_offset == 1;
OffsetType mask = other_offset == 1;
--mask;
uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr();
OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset();
offset &= mask;
return offset + other_offset;

//uintptr_t mask = -uintptr_t(other_offset != 1);
//uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr();
//OffsetType mask = -OffsetType(other_offset != 1);
//OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset();
//offset &= mask;
//return offset + other_offset;
#endif
Expand Down Expand Up @@ -215,9 +222,9 @@ namespace ipcdetail {
//!
//!<b>Note</b>: offset_ptr uses implementation defined properties, present in most platforms, for
//!performance reasons:
//! - Assumes that uintptr_t representation of nullptr is (uintptr_t)zero.
//! - Assumes that incrementing a uintptr_t obtained from a pointer is equivalent
//! to incrementing the pointer and then converting it back to uintptr_t.
//! - Assumes that OffsetType representation of nullptr is (OffsetType)zero.
//! - Assumes that incrementing a OffsetType obtained from a pointer is equivalent
//! to incrementing the pointer and then converting it back to OffsetType.
template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
class offset_ptr
{
Expand Down Expand Up @@ -251,86 +258,89 @@ class offset_ptr
//!Constructor from raw pointer (allows "0" pointer conversion).
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(pointer ptr) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(ptr, this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(ptr, this))
{}

//!Constructor from other pointer.
//!Never throws.
template <class T>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( T *ptr
, typename ipcdetail::enable_if< ::boost::is_convertible<T*, PointedType*> >::type * = 0) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr), this))
{}

//!Constructor from other offset_ptr
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr& ptr) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset)))
: internal(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset))
{}

//!Constructor from other offset_ptr. If pointers of pointee types are
//!convertible, offset_ptrs will be convertibles. Never throws.
//!Constructor from other offset_ptr. Only takes part in overload resolution
//!if T2* is convertible to PointedType*. Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
, typename ipcdetail::enable_if_convertible_equal_address<T2, PointedType>::type* = 0
#endif
) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset())))
: internal(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset()))
{}

#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED

//!Constructor from other offset_ptr. If pointers of pointee types are
//!convertible, offset_ptrs will be convertibles. Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
, typename ipcdetail::enable_if_convertible_unequal_address<T2, PointedType>::type* = 0) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
{}

#endif

//!Constructor from other offset_ptr. Only takes part in overload resolution
//!if PointedType* is constructible from T2* other than via a conversion (e.g. cast to a derived class). Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE explicit offset_ptr(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
, typename ipcdetail::enable_if_c<
!::boost::is_convertible<T2*, PointedType*>::value && ::boost::is_constructible<T2*, PointedType*>::value
>::type * = 0
#endif
) BOOST_NOEXCEPT
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
{}

//!Emulates static_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::static_cast_tag) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(r.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(r.get()), this))
{}

//!Emulates const_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::const_cast_tag) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(const_cast<PointedType*>(r.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(const_cast<PointedType*>(r.get()), this))
{}

//!Emulates dynamic_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::dynamic_cast_tag) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(dynamic_cast<PointedType*>(r.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(dynamic_cast<PointedType*>(r.get()), this))
{}

//!Emulates reinterpret_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::reinterpret_cast_tag) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(reinterpret_cast<PointedType*>(r.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(reinterpret_cast<PointedType*>(r.get()), this))
{}

//!Obtains raw pointer from offset.
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE pointer get() const BOOST_NOEXCEPT
{ return (pointer)ipcdetail::offset_ptr_to_raw_pointer(this, this->internal.m_offset); }
{ return static_cast<pointer>(ipcdetail::offset_ptr_to_raw_pointer(this, this->internal.m_offset)); }

BOOST_INTERPROCESS_FORCEINLINE offset_type get_offset() const BOOST_NOEXCEPT
{ return this->internal.m_offset; }
Expand Down Expand Up @@ -358,17 +368,15 @@ class offset_ptr
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (pointer from) BOOST_NOEXCEPT
{
this->internal.m_offset =
static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(from, this));
this->internal.m_offset = ipcdetail::offset_ptr_to_offset<OffsetType>(from, this);
return *this;
}

//!Assignment from other offset_ptr.
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (const offset_ptr & ptr) BOOST_NOEXCEPT
{
this->internal.m_offset =
static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset));
this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset);
return *this;
}

Expand Down Expand Up @@ -554,15 +562,13 @@ class offset_ptr
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr, ipcdetail::bool_<true>) BOOST_NOEXCEPT
{ //no need to pointer adjustment
this->internal.m_offset =
static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset()));
this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other<OffsetType>(this, &ptr, ptr.get_offset());
}

template<class T2>
BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr, ipcdetail::bool_<false>) BOOST_NOEXCEPT
{ //we must convert to raw before calculating the offset
this->internal.m_offset =
static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr.get()), this));
this->internal.m_offset = ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this);
}

#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
Expand Down Expand Up @@ -700,7 +706,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
typedef boost::interprocess::offset_ptr<T, P, O, A> pointer;
//Bits are stored in the lower bits of the pointer except the LSB,
//because this bit is used to represent the null pointer.
static const uintptr_t Mask = ((uintptr_t(1) << uintptr_t(NumBits)) - uintptr_t(1)) << uintptr_t(1);
static const O Mask = ((static_cast<O>(1) << NumBits) - static_cast<O>(1)) << 1;
BOOST_STATIC_ASSERT(0 ==(Mask&1));

//We must ALWAYS take argument "n" by reference as a copy of a null pointer
Expand All @@ -709,15 +715,15 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
BOOST_INTERPROCESS_FORCEINLINE static pointer get_pointer(const pointer &n) BOOST_NOEXCEPT
{
pointer p;
O const tmp_off = n.priv_offset() & O(~Mask);
O const tmp_off = n.priv_offset() & ~Mask;
p.priv_offset() = boost::interprocess::ipcdetail::offset_ptr_to_offset_from_other(&p, &n, tmp_off);
return p;
}

BOOST_INTERPROCESS_FORCEINLINE static void set_pointer(pointer &n, const pointer &p) BOOST_NOEXCEPT
{
BOOST_ASSERT(0 == (get_bits)(p));
O const stored_bits = O(n.priv_offset() & Mask);
O const stored_bits = n.priv_offset() & Mask;
n = p;
n.priv_offset() |= stored_bits;
}
Expand All @@ -731,7 +737,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
{
BOOST_ASSERT(b < (std::size_t(1) << NumBits));
O tmp = n.priv_offset();
tmp &= O(~Mask);
tmp &= ~Mask;
tmp |= O(b << 1u);
n.priv_offset() = tmp;
}
Expand Down

0 comments on commit acce62f

Please sign in to comment.