Browse Source

Added BX_OFFSETOF.

Бранимир Караџић 3 years ago
parent
commit
dbafa143d9
3 changed files with 50 additions and 0 deletions
  1. 12 0
      include/bx/bx.h
  2. 12 0
      include/bx/inline/bx.inl
  3. 26 0
      tests/macros_test.cpp

+ 12 - 0
include/bx/bx.h

@@ -21,6 +21,10 @@
 ///
 #define BX_COUNTOF(_x) sizeof(bx::CountOfRequireArrayArgumentT(_x) )
 
+///
+#define BX_OFFSETOF(_type, _member) \
+	(reinterpret_cast<ptrdiff_t>(&(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 <class Ty>
 	const Ty* addressOf(const Ty& _a);
 
+	///
+	template<typename Ty>
+	Ty* addressOf(void* _ptr, ptrdiff_t _offset);
+
+	///
+	template<typename Ty>
+	const Ty* addressOf(const void* _ptr, ptrdiff_t _offset);
+
 	/// Swap two values.
 	template<typename Ty>
 	void swap(Ty& _a, Ty& _b);

+ 12 - 0
include/bx/inline/bx.inl

@@ -53,6 +53,18 @@ namespace bx
 			);
 	}
 
+	template<typename Ty>
+	inline Ty* addressOf(void* _ptr, ptrdiff_t _offset)
+	{
+		return (Ty*)( (uint8_t*)_ptr + _offset);
+	}
+
+	template<typename Ty>
+	inline const Ty* addressOf(const void* _ptr, ptrdiff_t _offset)
+	{
+		return (const Ty*)( (const uint8_t*)_ptr + _offset);
+	}
+
 	template<typename Ty>
 	inline void swap(Ty& _a, Ty& _b)
 	{

+ 26 - 0
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) );
+	}
 }