Skip to content

Commit

Permalink
Improve pointer casting
Browse files Browse the repository at this point in the history
  • Loading branch information
morzhovets committed Dec 22, 2024
1 parent 99fc7a0 commit 55f8edb
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 73 deletions.
11 changes: 6 additions & 5 deletions include/momo/Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ class Array

Item* pvActivateInternalItems() noexcept
{
return &*::new(static_cast<void*>(std::addressof(mInternalItems))) InternalItems();
return (::new(static_cast<void*>(&mInternalItems)) InternalItems())->GetPtr();
}

void pvDestroy() noexcept
Expand All @@ -423,7 +423,7 @@ class Array
bool pvIsInternal() const noexcept
{
return (internalCapacity == 0) ? false
: static_cast<void*>(mItems) == std::addressof(mInternalItems);
: static_cast<void*>(mItems) == &mInternalItems;
}

bool pvReallocateInplace(size_t capacity, std::true_type /*canReallocateInplace*/)
Expand Down Expand Up @@ -1068,17 +1068,18 @@ class Array
size_t newCount = initCount + 1;
internal::ObjectBuffer<Item, ItemTraits::alignment> itemBuffer;
MemManager& memManager = GetMemManager();
typename ItemTraits::template Creator<const Item&>(memManager, item)(&itemBuffer);
typename ItemTraits::template Creator<const Item&>(memManager, item)(itemBuffer.GetPtr());
try
{
pvGrow(newCount, ArrayGrowCause::add);
}
catch (...)
{
ItemTraits::Destroy(memManager, &itemBuffer, 1);
ItemTraits::Destroy(memManager, itemBuffer.template GetPtr<true>(), 1);
throw;
}
ItemTraits::Relocate(memManager, &itemBuffer, GetItems() + initCount, 1);
ItemTraits::Relocate(memManager, itemBuffer.template GetPtr<true>(),
GetItems() + initCount, 1);
mData.SetCount(newCount);
}

Expand Down
6 changes: 3 additions & 3 deletions include/momo/ArrayUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,21 +160,21 @@ namespace internal
explicit ArrayItemHandler(MemManager& memManager, ItemCreator&& itemCreator)
: mMemManager(memManager)
{
std::forward<ItemCreator>(itemCreator)(&mItemBuffer);
std::forward<ItemCreator>(itemCreator)(mItemBuffer.GetPtr());
}

ArrayItemHandler(const ArrayItemHandler&) = delete;

~ArrayItemHandler() noexcept
{
ItemTraits::Destroy(mMemManager, &mItemBuffer, 1);
ItemTraits::Destroy(mMemManager, &*this, 1);
}

ArrayItemHandler& operator=(const ArrayItemHandler&) = delete;

Item* operator&() noexcept
{
return &mItemBuffer;
return std::addressof(mItemBuffer.Get());
}

private:
Expand Down
6 changes: 3 additions & 3 deletions include/momo/MapUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -586,17 +586,17 @@ namespace internal

const Key* GetKeyPtr() const noexcept
{
return &mKeyBuffer;
return mKeyBuffer.template GetPtr<true>();
}

Key* GetKeyPtr() noexcept
{
return &mKeyBuffer;
return mKeyBuffer.GetPtr();
}

Value* GetValuePtr() const noexcept
{
return &mValueBuffer;
return mValueBuffer.GetPtr();
}

private:
Expand Down
32 changes: 24 additions & 8 deletions include/momo/ObjectManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,30 @@ namespace internal

ObjectBuffer& operator=(const ObjectBuffer&) = delete;

const Object* operator&() const noexcept
template<bool isWithinLifetime = false>
const Object* GetPtr() const noexcept
{
return PtrCaster::FromBytePtr<Object>(static_cast<const void*>(&mBuffer));
return PtrCaster::FromBytePtr<Object, isWithinLifetime, count == 1>(
static_cast<const void*>(&mBuffer));
}

Object* operator&() noexcept
template<bool isWithinLifetime = false>
Object* GetPtr() noexcept
{
return PtrCaster::FromBytePtr<Object>(static_cast<void*>(&mBuffer));
return PtrCaster::FromBytePtr<Object, isWithinLifetime, count == 1>(
static_cast<void*>(&mBuffer));
}

const Object& Get() const noexcept
{
MOMO_STATIC_ASSERT(count == 1);
return *GetPtr<true>();
}

Object& Get() noexcept
{
MOMO_STATIC_ASSERT(count == 1);
return *GetPtr<true>();
}

private:
Expand Down Expand Up @@ -437,9 +453,9 @@ namespace internal
if (std::addressof(srcObject) != std::addressof(dstObject))
{
ObjectBuffer<Object, alignment> objectBuffer;
Relocate(memManager, dstObject, &objectBuffer);
Relocate(memManager, dstObject, objectBuffer.GetPtr());
Relocate(memManager, srcObject, std::addressof(dstObject));
Relocate(memManager, *&objectBuffer, std::addressof(srcObject));
Relocate(memManager, objectBuffer.Get(), std::addressof(srcObject));
}
}

Expand Down Expand Up @@ -539,11 +555,11 @@ namespace internal
std::true_type /*isNothrowRelocatable*/, BoolConstant<isNothrowSwappable>) noexcept
{
ObjectBuffer<Object, alignment> objectBuffer;
Relocate(memManager, *begin, &objectBuffer);
Relocate(memManager, *begin, objectBuffer.GetPtr());
Iterator iter = begin;
for (size_t i = 0; i < shift; ++i, (void)++iter)
Relocate(memManager, *std::next(iter), std::addressof(*iter));
Relocate(memManager, *&objectBuffer, std::addressof(*iter));
Relocate(memManager, objectBuffer.Get(), std::addressof(*iter));
}

template<typename Iterator>
Expand Down
23 changes: 12 additions & 11 deletions include/momo/SetUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ namespace internal
explicit SetCrew(const ContainerTraits& containerTraits, MemManager&& memManager)
{
mData = MemManagerProxy::template AllocateCreate<Data>(memManager, containerTraits);
::new(static_cast<void*>(&mData->memManagerBuffer)) MemManager(std::move(memManager));
::new(static_cast<void*>(mData->memManagerBuffer.GetPtr())) MemManager(std::move(memManager));
}

SetCrew(SetCrew&& crew) noexcept
Expand All @@ -126,8 +126,9 @@ namespace internal
{
if (!pvIsNull())
{
MemManager memManager = std::move(GetMemManager());
(&mData->memManagerBuffer)->~MemManager();
MemManager* memManagerPtr = &GetMemManager();
MemManager memManager = std::move(*memManagerPtr);
memManagerPtr->~MemManager();
mData->~Data();
MemManagerProxy::Deallocate(memManager, mData, sizeof(Data));
}
Expand Down Expand Up @@ -161,13 +162,13 @@ namespace internal
const MemManager& GetMemManager() const noexcept
{
MOMO_ASSERT(!pvIsNull());
return *&mData->memManagerBuffer;
return mData->memManagerBuffer.Get();
}

MemManager& GetMemManager() noexcept
{
MOMO_ASSERT(!pvIsNull());
return *&mData->memManagerBuffer;
return mData->memManagerBuffer.Get();
}

private:
Expand Down Expand Up @@ -279,7 +280,7 @@ namespace internal
: mHasItem(extractedItem.mHasItem)
{
if (mHasItem)
ItemTraits::Relocate(nullptr, *&extractedItem.mItemBuffer, &mItemBuffer);
ItemTraits::Relocate(nullptr, extractedItem.mItemBuffer.Get(), mItemBuffer.GetPtr());
extractedItem.mHasItem = false;
}

Expand All @@ -300,35 +301,35 @@ namespace internal
void Clear() noexcept
{
if (mHasItem)
ItemTraits::Destroy(nullptr, *&mItemBuffer);
ItemTraits::Destroy(nullptr, mItemBuffer.Get());
mHasItem = false;
}

const Item& GetItem() const
{
MOMO_CHECK(mHasItem);
return *&mItemBuffer;
return mItemBuffer.Get();
}

Item& GetItem()
{
MOMO_CHECK(mHasItem);
return *&mItemBuffer;
return mItemBuffer.Get();
}

template<typename ItemCreator>
void Create(ItemCreator&& itemCreator)
{
MOMO_CHECK(!mHasItem);
std::forward<ItemCreator>(itemCreator)(&mItemBuffer);
std::forward<ItemCreator>(itemCreator)(mItemBuffer.GetPtr());
mHasItem = true;
}

template<typename ItemRemover>
void Remove(ItemRemover&& itemRemover)
{
MOMO_CHECK(mHasItem);
std::forward<ItemRemover>(itemRemover)(*&mItemBuffer);
std::forward<ItemRemover>(itemRemover)(mItemBuffer.Get());
mHasItem = false;
}

Expand Down
5 changes: 3 additions & 2 deletions include/momo/Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ namespace internal
|| std::is_void<QResObject>::value, QResObject*>
pvFromBytePtr(QByte* bytePtr) noexcept
{
MOMO_STATIC_ASSERT(!isWithinLifetime && !isSingleObject);
MOMO_STATIC_ASSERT(!std::is_void<QResObject>::value
|| (!isWithinLifetime && !isSingleObject));
return static_cast<QResObject*>(bytePtr);
}

Expand All @@ -304,7 +305,7 @@ namespace internal
&& !std::is_void<QResObject>::value, QResObject*>
pvFromBytePtr(QByte* bytePtr) noexcept
{
//MOMO_STATIC_ASSERT(isWithinLifetime || !std::is_const<QResObject>::value);
MOMO_STATIC_ASSERT(!std::is_const<QResObject>::value || isWithinLifetime);
return MOMO_CAST_POINTER(QResObject, bytePtr, isWithinLifetime, isSingleObject);
}
};
Expand Down
22 changes: 15 additions & 7 deletions include/momo/details/HashBucketOne.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace internal

Bounds GetBounds(Params& /*params*/) noexcept
{
return IsFull() ? Bounds(&mItemBuffer, 1) : Bounds();
return IsFull() ? Bounds(pvGetItemPtr(), 1) : Bounds();
}

template<bool first, typename ItemPredicate>
Expand All @@ -78,7 +78,8 @@ namespace internal
{
if (mHashState != pvGetHashState(hashCode))
return nullptr;
return itemPred(*&mItemBuffer) ? &mItemBuffer : nullptr;
Item* itemPtr = pvGetItemPtr();
return itemPred(*itemPtr) ? itemPtr : nullptr;
}

bool IsFull() const noexcept
Expand All @@ -102,18 +103,19 @@ namespace internal
noexcept(noexcept(std::forward<ItemCreator>(itemCreator)(std::declval<Item*>())))
{
MOMO_ASSERT(!IsFull());
std::forward<ItemCreator>(itemCreator)(&mItemBuffer);
std::forward<ItemCreator>(itemCreator)(pvGetItemPtr<false>());
mHashState = pvGetHashState(hashCode);
return &mItemBuffer;
return pvGetItemPtr();
}

template<typename ItemReplacer>
Iterator Remove(Params& /*params*/, Iterator iter, ItemReplacer&& itemReplacer)
{
(void)iter;
MOMO_ASSERT(iter == &mItemBuffer);
MOMO_ASSERT(IsFull());
std::forward<ItemReplacer>(itemReplacer)(*&mItemBuffer, *&mItemBuffer);
Item* itemPtr = pvGetItemPtr();
MOMO_ASSERT(iter == itemPtr);
std::forward<ItemReplacer>(itemReplacer)(*itemPtr, *itemPtr);
mHashState = HashState{2};
return nullptr;
}
Expand All @@ -123,7 +125,7 @@ namespace internal
size_t /*bucketIndex*/, size_t /*logBucketCount*/, size_t /*newLogBucketCount*/)
{
(void)iter;
MOMO_ASSERT(iter == &mItemBuffer);
MOMO_ASSERT(iter == pvGetItemPtr());
if (sizeof(HashState) < sizeof(size_t))
return hashCodeFullGetter();
return static_cast<size_t>(mHashState >> 1);
Expand All @@ -145,6 +147,12 @@ namespace internal
return (static_cast<HashState>(hashCode) << 1) | 1;
}

template<bool isWithinLifetime = true>
Item* pvGetItemPtr() noexcept
{
return mItemBuffer.template GetPtr<isWithinLifetime>();
}

private:
HashState mHashState;
ObjectBuffer<Item, ItemTraits::alignment> mItemBuffer;
Expand Down
19 changes: 12 additions & 7 deletions include/momo/details/HashBucketOpen2N2.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ namespace internal

Bounds GetBounds(Params& /*params*/) noexcept
{
return Bounds(Iterator(&mItems + maxCount), pvGetCount());
return Bounds(Iterator(mItems.GetPtr() + maxCount), pvGetCount());
}

template<bool first, typename ItemPredicate>
Expand All @@ -103,8 +103,12 @@ namespace internal
ShortHash shortHash = pvCalcShortHash(hashCode);
for (size_t i = 0; i < maxCount; ++i)
{
if (mHashData.shortHashes[i] == shortHash && itemPred((&mItems)[i]))
return Iterator(&mItems + i + 1);
if (mHashData.shortHashes[i] == shortHash)
{
Item* items = mItems.GetPtr();
if (itemPred(items[i]))
return Iterator(items + i + 1);
}
}
return Iterator();
}
Expand Down Expand Up @@ -148,7 +152,7 @@ namespace internal
{
size_t count = pvGetCount();
MOMO_ASSERT(count < maxCount);
Item* newItem = &mItems + maxCount - 1 - count;
Item* newItem = mItems.GetPtr() + maxCount - 1 - count;
std::forward<ItemCreator>(itemCreator)(newItem);
mHashData.shortHashes[maxCount - 1 - count] = pvCalcShortHash(hashCode);
if (useHashCodePartGetter)
Expand All @@ -168,9 +172,10 @@ namespace internal
Iterator Remove(Params& /*params*/, Iterator iter, ItemReplacer&& itemReplacer)
{
size_t count = pvGetCount();
size_t index = UIntMath<>::Dist(&mItems, std::addressof(*iter));
Item* items = mItems.GetPtr();
size_t index = UIntMath<>::Dist(items, std::addressof(*iter));
MOMO_ASSERT(index >= maxCount - count);
std::forward<ItemReplacer>(itemReplacer)((&mItems)[maxCount - count], (&mItems)[index]);
std::forward<ItemReplacer>(itemReplacer)(items[maxCount - count], items[index]);
mHashData.shortHashes[index] = mHashData.shortHashes[maxCount - count];
mHashData.shortHashes[maxCount - count] = emptyShortHash;
if (useHashCodePartGetter)
Expand All @@ -185,7 +190,7 @@ namespace internal
{
if (!useHashCodePartGetter)
return hashCodeFullGetter();
size_t index = UIntMath<>::Dist(&mItems, std::addressof(*iter));
size_t index = UIntMath<>::Dist(mItems.GetPtr(), std::addressof(*iter));
uint8_t hashProbe = mHashData.hashProbes[index];
bool useFullGetter = (hashProbe == emptyHashProbe ||
(logBucketCount + logBucketCountAddend) / logBucketCountStep
Expand Down
10 changes: 7 additions & 3 deletions include/momo/details/HashBucketOpenN1.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,12 @@ namespace internal
const uint8_t* thisShortHashes = pvGetShortHashes();
for (size_t i = 0; i < maxCount; ++i)
{
if (thisShortHashes[i] == shortHash && itemPred(*&mItems[i]))
return pvMakeIterator(&mItems[i]);
if (thisShortHashes[i] == shortHash)
{
Item* itemPtr = mItems[i].template GetPtr<true>();
if (itemPred(*itemPtr))
return pvMakeIterator(itemPtr);
}
}
return Iterator();
}
Expand Down Expand Up @@ -158,7 +162,7 @@ namespace internal

Item* ptGetItemPtr(size_t index) noexcept
{
return &mItems[reverse ? maxCount - 1 - index : index];
return mItems[reverse ? maxCount - 1 - index : index].GetPtr();
}

static uint8_t ptCalcShortHash(size_t hashCode) noexcept
Expand Down
Loading

0 comments on commit 55f8edb

Please sign in to comment.