diff --git a/include/bx/bx.h b/include/bx/bx.h index c84e76f..099dc33 100644 --- a/include/bx/bx.h +++ b/include/bx/bx.h @@ -21,6 +21,10 @@ /// #define BX_COUNTOF(_x) sizeof(bx::CountOfRequireArrayArgumentT(_x) ) +/// +#define BX_OFFSETOF(_type, _member) \ + (reinterpret_cast(&(reinterpret_cast<_type*>(16)->_member) )-ptrdiff_t(16) ) + /// #if BX_COMPILER_MSVC # define BX_IGNORE_C4127(_x) bx::ignoreC4127(!!(_x) ) @@ -45,6 +49,14 @@ namespace bx template const Ty* addressOf(const Ty& _a); + /// + template + Ty* addressOf(void* _ptr, ptrdiff_t _offset); + + /// + template + const Ty* addressOf(const void* _ptr, ptrdiff_t _offset); + /// Swap two values. template void swap(Ty& _a, Ty& _b); diff --git a/include/bx/inline/bx.inl b/include/bx/inline/bx.inl index 4b07f29..1639d77 100644 --- a/include/bx/inline/bx.inl +++ b/include/bx/inline/bx.inl @@ -53,6 +53,18 @@ namespace bx ); } + template + inline Ty* addressOf(void* _ptr, ptrdiff_t _offset) + { + return (Ty*)( (uint8_t*)_ptr + _offset); + } + + template + inline const Ty* addressOf(const void* _ptr, ptrdiff_t _offset) + { + return (const Ty*)( (const uint8_t*)_ptr + _offset); + } + template inline void swap(Ty& _a, Ty& _b) { diff --git a/tests/macros_test.cpp b/tests/macros_test.cpp index 7870680..75081b9 100644 --- a/tests/macros_test.cpp +++ b/tests/macros_test.cpp @@ -47,4 +47,30 @@ TEST(macros) CHECK_EQUAL(6, BX_VA_ARGS_COUNT(1, 2, 3, 4, 5, 6) ); CHECK_EQUAL(0, bx::strCmp(BX_STRINGIZE(TEST 1234 %^&*), "TEST 1234 %^&*") ); + + { + struct PodStruct { int32_t x, y, z; }; + CHECK_EQUAL(0, BX_OFFSETOF(PodStruct, x) ); + CHECK_EQUAL(4, BX_OFFSETOF(PodStruct, y) ); + CHECK_EQUAL(8, BX_OFFSETOF(PodStruct, z) ); + } + + { + union PodUnion { int32_t x, y, z; }; + CHECK_EQUAL(BX_OFFSETOF(PodUnion, x), BX_OFFSETOF(PodUnion, y) ); + CHECK_EQUAL(BX_OFFSETOF(PodUnion, y), BX_OFFSETOF(PodUnion, z) ); + } + + { + struct NonPodStruct { NonPodStruct() { } int32_t x, y, z; }; + CHECK_EQUAL(0, BX_OFFSETOF(NonPodStruct, x) ); + CHECK_EQUAL(4, BX_OFFSETOF(NonPodStruct, y) ); + CHECK_EQUAL(8, BX_OFFSETOF(NonPodStruct, z) ); + } + + { + union NonPodUnion { NonPodUnion() { } int32_t x, y, z; }; + CHECK_EQUAL(BX_OFFSETOF(NonPodUnion, x), BX_OFFSETOF(NonPodUnion, y) ); + CHECK_EQUAL(BX_OFFSETOF(NonPodUnion, y), BX_OFFSETOF(NonPodUnion, z) ); + } }