#include <iostream>
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#ifndef UINT64_C
#define UINT64_C(n) n##ULL
#endif
static const uint64_t stchkValue = UINT64_C(0xbbbbfeedfacebbbb);
static const uint64_t enchkValue = UINT64_C(0xeeeefeedfaceeeee);
template<typename T>
struct Item
{
uint64_t stchk;
union {
char mem[sizeof(T)];
//__m128i align; ideone compiler options disallow
} data;
uint64_t enchk;
Item()
: stchk(stchkValue)
, enchk(enchkValue)
{
}
void construct()
{
new (&data) T();
}
};
template<typename T>
static void destruct(T *p)
{
// Try to reverse calculate the Item pointer from the mem pointer
// tried auto ofs = offsetof(Item<T>, data);
// tried auto ofs = offsetof(Item, data);
typedef Item<T> NiceItem;
auto ofs = offsetof(NiceItem, data);
//auto ofs = (size_t)(uintptr_t)(&((T*)0)->data);
std::cout << "offset is " << ofs << std::endl;
auto self = reinterpret_cast<Item<T>*>((uintptr_t)p - ofs);
assert(self->stchk == stchkValue);
assert(self->enchk == enchkValue);
assert(reinterpret_cast<T*>(self->data.mem) == p);
p->~T();
}
int main()
{
Item<int> x;
x.construct();
auto p = &x.data;
destruct(p);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RkaW50Lmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2lmbmRlZiBVSU5UNjRfQwojZGVmaW5lIFVJTlQ2NF9DKG4pIG4jI1VMTAojZW5kaWYKCnN0YXRpYyBjb25zdCB1aW50NjRfdCBzdGNoa1ZhbHVlID0gVUlOVDY0X0MoMHhiYmJiZmVlZGZhY2ViYmJiKTsKc3RhdGljIGNvbnN0IHVpbnQ2NF90IGVuY2hrVmFsdWUgPSBVSU5UNjRfQygweGVlZWVmZWVkZmFjZWVlZWUpOwogICAgCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBJdGVtCnsKICAgIHVpbnQ2NF90IHN0Y2hrOwogICAgdW5pb24gewogICAgICAgIGNoYXIgbWVtW3NpemVvZihUKV07CiAgICAgICAgLy9fX20xMjhpIGFsaWduOyBpZGVvbmUgY29tcGlsZXIgb3B0aW9ucyBkaXNhbGxvdwogICAgfSBkYXRhOwogICAgdWludDY0X3QgZW5jaGs7CiAgICAKICAgIEl0ZW0oKQogICAgIDogc3RjaGsoc3RjaGtWYWx1ZSkKICAgICAsIGVuY2hrKGVuY2hrVmFsdWUpCiAgICB7CiAgICB9CiAgICAKICAgIHZvaWQgY29uc3RydWN0KCkKICAgIHsKICAgICAgICBuZXcgKCZkYXRhKSBUKCk7CiAgICB9Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdGF0aWMgdm9pZCBkZXN0cnVjdChUICpwKQp7CiAgICAvLyBUcnkgdG8gcmV2ZXJzZSBjYWxjdWxhdGUgdGhlIEl0ZW0gcG9pbnRlciBmcm9tIHRoZSBtZW0gcG9pbnRlcgogICAgLy8gdHJpZWQgYXV0byBvZnMgPSBvZmZzZXRvZihJdGVtPFQ+LCBkYXRhKTsKICAgIC8vIHRyaWVkIGF1dG8gb2ZzID0gb2Zmc2V0b2YoSXRlbSwgZGF0YSk7CiAgICB0eXBlZGVmIEl0ZW08VD4gTmljZUl0ZW07CiAgICBhdXRvIG9mcyA9IG9mZnNldG9mKE5pY2VJdGVtLCBkYXRhKTsKICAgIC8vYXV0byBvZnMgPSAoc2l6ZV90KSh1aW50cHRyX3QpKCYoKFQqKTApLT5kYXRhKTsKICAgIAogICAgc3RkOjpjb3V0IDw8ICJvZmZzZXQgaXMgIiA8PCBvZnMgPDwgc3RkOjplbmRsOwogICAgCiAgICBhdXRvIHNlbGYgPSByZWludGVycHJldF9jYXN0PEl0ZW08VD4qPigodWludHB0cl90KXAgLSBvZnMpOwogICAgYXNzZXJ0KHNlbGYtPnN0Y2hrID09IHN0Y2hrVmFsdWUpOwogICAgYXNzZXJ0KHNlbGYtPmVuY2hrID09IGVuY2hrVmFsdWUpOwogICAgYXNzZXJ0KHJlaW50ZXJwcmV0X2Nhc3Q8VCo+KHNlbGYtPmRhdGEubWVtKSA9PSBwKTsKICAgIAogICAgcC0+flQoKTsKfQoKaW50IG1haW4oKQp7CiAgICBJdGVtPGludD4geDsKICAgIHguY29uc3RydWN0KCk7CiAgICBhdXRvIHAgPSAmeC5kYXRhOwogICAgZGVzdHJ1Y3QocCk7Cn0K