summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2023-04-30 18:40:07 +0330
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2023-05-02 17:46:39 +0330
commit2306219ef9151229974c03ecf52e84f3d84a254d (patch)
treebc48cdc12307f4edb20db63b32c64d5ed233378b
parentbe7bc414701193fd0f40ed5d01c020b9362bda82 (diff)
downloadserenity-2306219ef9151229974c03ecf52e84f3d84a254d.zip
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.
-rw-r--r--AK/IntrusiveList.h9
1 files changed, 8 insertions, 1 deletions
diff --git a/AK/IntrusiveList.h b/AK/IntrusiveList.h
index 9475efd492..b671a7a11c 100644
--- a/AK/IntrusiveList.h
+++ b/AK/IntrusiveList.h
@@ -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>