summaryrefslogtreecommitdiff
path: root/AK
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 /AK
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.
Diffstat (limited to 'AK')
-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>