AK: Accomodate always-32-bit data member pointers in IntrusiveList

This only exists on windows, but we've made an effort to keep jakt
working on windows, so let's support this silliness.
This commit is contained in:
Ali Mohammad Pur 2023-04-30 18:40:07 +03:30 committed by Ali Mohammad Pur
parent be7bc41470
commit 2306219ef9
Notes: sideshowbarker 2024-07-17 17:49:11 +09:00

View File

@ -375,13 +375,20 @@ inline typename IntrusiveList<T, Container, member>::ConstIterator IntrusiveList
template<class T, typename Container, SubstitutedIntrusiveListNode<T, Container> T::*member>
inline T* IntrusiveList<T, Container, member>::node_to_value(SubstitutedIntrusiveListNode<T, Container>& node)
{
// Note: A data member pointer is a 32-bit offset in the Windows ABI (both x86 and x86_64),
// whereas it is an appropriately sized ptrdiff_t in the Itanium ABI, the following ensures
// that we always use the correct type for the subtraction.
using EquivalentNumericTypeForDataMemberPointer = Conditional<sizeof(member) == sizeof(ptrdiff_t), ptrdiff_t, u32>;
static_assert(sizeof(EquivalentNumericTypeForDataMemberPointer) == sizeof(member),
"The equivalent numeric type for the data member pointer must have the same size as the data member pointer itself.");
// Note: Since this might seem odd, here's an explanation on what this function actually does:
// `node` is a reference that resides in some part of the actual value (of type T), the
// placement (i.e. offset) of which is described by the pointer-to-data-member parameter
// named `member`.
// This function effectively takes in the address of the data member, and returns the address
// of the value (of type T) holding that member.
return bit_cast<T*>(bit_cast<unsigned char*>(&node) - bit_cast<unsigned char*>(member));
return bit_cast<T*>(bit_cast<unsigned char*>(&node) - bit_cast<EquivalentNumericTypeForDataMemberPointer>(member));
}
template<typename T, typename Container>