mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
fix fields not working on macos? hopefully
This commit is contained in:
parent
db32732d47
commit
aaf62584fb
1 changed files with 75 additions and 91 deletions
|
@ -66,120 +66,104 @@ namespace geode::modifier {
|
|||
public:
|
||||
// the constructor that constructs the fields.
|
||||
// we construct the Parent first,
|
||||
static void fieldConstructor(void* offsetField) requires (!HasFields<Parent>) {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
static void fieldConstructor(void* offsetField) {
|
||||
if constexpr (HasFields<Parent>) {
|
||||
(void) new (offsetField) typename Parent::Fields();
|
||||
}
|
||||
else {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
|
||||
auto parent = new (parentContainer.data()) Parent();
|
||||
auto parent = new (parentContainer.data()) Parent();
|
||||
|
||||
parent->Intermediate::~Intermediate();
|
||||
parent->Intermediate::~Intermediate();
|
||||
|
||||
std::memcpy(
|
||||
offsetField,
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
std::memcpy(
|
||||
offsetField,
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void fieldDestructor(void* offsetField) requires (!HasFields<Parent>) {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
static void fieldDestructor(void* offsetField) {
|
||||
if constexpr (HasFields<Parent>) {
|
||||
static_cast<typename Parent::Fields*>(offsetField)->~Fields();
|
||||
}
|
||||
else {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
|
||||
auto parent = new (parentContainer.data()) Intermediate();
|
||||
auto parent = new (parentContainer.data()) Intermediate();
|
||||
|
||||
std::memcpy(
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
offsetField,
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
|
||||
static_cast<Parent*>(parent)->Parent::~Parent();
|
||||
}
|
||||
|
||||
operator Parent*() requires (!HasFields<Parent>) {
|
||||
// get the this pointer of the base
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we canget the base from ourself
|
||||
auto node = reinterpret_cast<Parent*>(reinterpret_cast<std::byte*>(this) - sizeof(Base));
|
||||
static_assert(sizeof(Base) == offsetof(Parent, m_fields), "offsetof not correct");
|
||||
|
||||
// generating the container if it doesn't exist
|
||||
auto container = FieldContainer::from(node, typeid(Base).name());
|
||||
|
||||
// the index is global across all mods, so the
|
||||
// function is defined in the loader source
|
||||
static size_t index = getFieldIndexForClass(typeid(Base).name());
|
||||
|
||||
// the fields are actually offset from their original
|
||||
// offset, this is done to save on allocation and space
|
||||
auto offsetField = container->getField(index);
|
||||
if (!offsetField) {
|
||||
offsetField = container->setField(
|
||||
index, sizeof(Parent) - sizeof(Intermediate), &FieldIntermediate::fieldDestructor
|
||||
std::memcpy(
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
offsetField,
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
|
||||
FieldIntermediate::fieldConstructor(offsetField);
|
||||
static_cast<Parent*>(parent)->Parent::~Parent();
|
||||
}
|
||||
|
||||
return reinterpret_cast<Parent*>(
|
||||
reinterpret_cast<std::byte*>(offsetField) - sizeof(Intermediate)
|
||||
);
|
||||
}
|
||||
|
||||
Parent* self() requires (!HasFields<Parent>) {
|
||||
return this->operator Parent*();
|
||||
}
|
||||
auto self() {
|
||||
if constexpr (HasFields<Parent>) {
|
||||
// get the this pointer of the base
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we canget the base from ourself
|
||||
auto node = reinterpret_cast<Parent*>(reinterpret_cast<std::byte*>(this) - sizeof(Base));
|
||||
static_assert(sizeof(Base) == offsetof(Parent, m_fields), "offsetof not correct");
|
||||
|
||||
Parent* operator->() requires (!HasFields<Parent>) {
|
||||
// workaround for "static assertion is not an integral constant expression" in CLion
|
||||
// while the solution in https://github.com/microsoft/STL/issues/3311 works, you can't provide
|
||||
// cli args to clang-tidy in clion, so we use this workaround instead
|
||||
// https://youtrack.jetbrains.com/issue/CPP-27446/spurious-offsetof-in-staticassert-error-from-clangd#focus=Comments-27-8172811.0-0
|
||||
// update: that workaround didn't work,
|
||||
// undefining and re-defining offsetof caused another error further down
|
||||
// so we're doing this now
|
||||
#ifdef __CLION_IDE__
|
||||
return reinterpret_cast<Parent*>(69420);
|
||||
#else
|
||||
return this->operator Parent*();
|
||||
#endif
|
||||
}
|
||||
// generating the container if it doesn't exist
|
||||
auto container = FieldContainer::from(node, typeid(Base).name());
|
||||
|
||||
static void fieldConstructor(void* offsetField) requires (HasFields<Parent>) {
|
||||
(void) new (offsetField) typename Parent::Fields();
|
||||
}
|
||||
// the index is global across all mods, so the
|
||||
// function is defined in the loader source
|
||||
static size_t index = getFieldIndexForClass(typeid(Base).name());
|
||||
|
||||
static void fieldDestructor(void* offsetField) requires (HasFields<Parent>) {
|
||||
static_cast<typename Parent::Fields*>(offsetField)->~Fields();
|
||||
}
|
||||
// the fields are actually offset from their original
|
||||
// offset, this is done to save on allocation and space
|
||||
auto offsetField = container->getField(index);
|
||||
if (!offsetField) {
|
||||
offsetField = container->setField(
|
||||
index, sizeof(typename Parent::Fields), &FieldIntermediate::fieldDestructor
|
||||
);
|
||||
|
||||
auto self() requires (HasFields<Parent>) {
|
||||
// get the this pointer of the base
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we canget the base from ourself
|
||||
auto node = reinterpret_cast<Parent*>(reinterpret_cast<std::byte*>(this) - sizeof(Base));
|
||||
static_assert(sizeof(Base) == offsetof(Parent, m_fields), "offsetof not correct");
|
||||
FieldIntermediate::fieldConstructor(offsetField);
|
||||
}
|
||||
|
||||
// generating the container if it doesn't exist
|
||||
auto container = FieldContainer::from(node, typeid(Base).name());
|
||||
return reinterpret_cast<typename Parent::Fields*>(offsetField);
|
||||
}
|
||||
else {
|
||||
// get the this pointer of the base
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we canget the base from ourself
|
||||
auto node = reinterpret_cast<Parent*>(reinterpret_cast<std::byte*>(this) - sizeof(Base));
|
||||
static_assert(sizeof(Base) == offsetof(Parent, m_fields), "offsetof not correct");
|
||||
|
||||
// the index is global across all mods, so the
|
||||
// function is defined in the loader source
|
||||
static size_t index = getFieldIndexForClass(typeid(Base).name());
|
||||
// generating the container if it doesn't exist
|
||||
auto container = FieldContainer::from(node, typeid(Base).name());
|
||||
|
||||
// the fields are actually offset from their original
|
||||
// offset, this is done to save on allocation and space
|
||||
auto offsetField = container->getField(index);
|
||||
if (!offsetField) {
|
||||
offsetField = container->setField(
|
||||
index, sizeof(typename Parent::Fields), &FieldIntermediate::fieldDestructor
|
||||
// the index is global across all mods, so the
|
||||
// function is defined in the loader source
|
||||
static size_t index = getFieldIndexForClass(typeid(Base).name());
|
||||
|
||||
// the fields are actually offset from their original
|
||||
// offset, this is done to save on allocation and space
|
||||
auto offsetField = container->getField(index);
|
||||
if (!offsetField) {
|
||||
offsetField = container->setField(
|
||||
index, sizeof(Parent) - sizeof(Intermediate), &FieldIntermediate::fieldDestructor
|
||||
);
|
||||
|
||||
FieldIntermediate::fieldConstructor(offsetField);
|
||||
}
|
||||
|
||||
return reinterpret_cast<Parent*>(
|
||||
reinterpret_cast<std::byte*>(offsetField) - sizeof(Intermediate)
|
||||
);
|
||||
|
||||
FieldIntermediate::fieldConstructor(offsetField);
|
||||
}
|
||||
|
||||
return reinterpret_cast<typename Parent::Fields*>(offsetField);
|
||||
}
|
||||
|
||||
auto operator->() requires (HasFields<Parent>) {
|
||||
auto operator->() {
|
||||
// workaround for "static assertion is not an integral constant expression" in CLion
|
||||
// while the solution in https://github.com/microsoft/STL/issues/3311 works, you can't provide
|
||||
// cli args to clang-tidy in clion, so we use this workaround instead
|
||||
|
|
Loading…
Reference in a new issue