Skip to content

Commit 59aa219

Browse files
committed
Allow to use custom user types, part 2
1 parent 50a2f41 commit 59aa219

1 file changed

Lines changed: 89 additions & 12 deletions

File tree

vecmath.h

Lines changed: 89 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -961,27 +961,34 @@ if using clang (gcc and tcc use similar syntax).
961961
#define VECMATH_INLINE static inline
962962
#endif
963963

964+
#define VECMATH_SIZEOF(x) sizeof(x)
965+
#define VECMATH_OFFSETOF(st, m) ((long long unsigned)&(((st *)0)->m))
966+
#define VECMATH_STATIC_ASSERT(condition, message) int VECMATH_STATIC_ASSERT(int VECMATH_STATIC_ASSERT[(condition) ? 1 : -1])
967+
968+
struct vecmath_static_assert_test { char x; };
969+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(struct vecmath_static_assert_test) == 1, "vecmath static assert test 1");
970+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(struct vecmath_static_assert_test, x) == 0, "vecmath static assert test 2");
971+
964972
#ifdef __cplusplus
965973
namespace vecmath {
966974
#endif
967975

968976
// types
977+
#if defined( VECMATH_VEC2 ) || defined( VECMATH_VEC3 ) || defined( VECMATH_VEC4 ) || \
978+
defined( VECMATH_MAT22 ) || defined( VECMATH_MAT23 ) || defined( VECMATH_MAT24 ) || \
979+
defined( VECMATH_MAT32 ) || defined( VECMATH_MAT33 ) || defined( VECMATH_MAT34 ) || \
980+
defined( VECMATH_MAT42 ) || defined( VECMATH_MAT43 ) || defined( VECMATH_MAT44 )
981+
982+
#if defined( VECMATH_EXT_VECTOR_TYPE )
983+
#error "VECMATH_EXT_VECTOR_TYPE is incompatible with custom types. If you want to use clang vector extensions with your own types, you need to decorate your types with the necessary attributes."
984+
#endif
985+
986+
#endif
987+
969988
#if defined( VECMATH_EXT_VECTOR_TYPE ) && !defined( __cplusplus ) && defined(__clang__) && __clang_major__ >= 3
970-
#if !defined( VECMATH_VEC2 )
971989
typedef float vec2_t __attribute__((ext_vector_type(2)));
972-
#else
973-
typedef VECMATH_VEC2 vec2_t;
974-
#endif
975-
#if !defined( VECMATH_VEC3 )
976990
typedef float vec3_t __attribute__((ext_vector_type(3)));
977-
#else
978-
typedef VECMATH_VEC3 vec3_t;
979-
#endif
980-
#if !defined( VECMATH_VEC3 )
981991
typedef float vec4_t __attribute__((ext_vector_type(4)));
982-
#else
983-
typedef VECMATH_VEC4 vec4_t;
984-
#endif
985992
#else
986993
#if !defined( VECMATH_VEC2 )
987994
typedef struct vec2_t { float x, y; } vec2_t ;
@@ -1045,6 +1052,76 @@ if using clang (gcc and tcc use similar syntax).
10451052
typedef VECMATH_MAT44 mat44_t;
10461053
#endif
10471054

1055+
/* The _get/_set (accessing by index) functions assume the x/y/z/w members are
1056+
* in that specific order, starts at the start of the struct, and that there's
1057+
* no padding. The following static assertions ensure all of this is true. */
1058+
1059+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec2_t, x) == 0, "vecmath vec2_t type member 'x' must be at offset 0");
1060+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec2_t, y) == 4, "vecmath vec2_t type member 'y' must be at offset 4");
1061+
1062+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec3_t, x) == 0, "vecmath vec3_t type member 'x' must be at offset 0");
1063+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec3_t, y) == 4, "vecmath vec3_t type member 'y' must be at offset 4");
1064+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec3_t, z) == 8, "vecmath vec3_t type member 'z' must be at offset 8");
1065+
1066+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec4_t, x) == 0, "vecmath vec3_t type member 'x' must be at offset 0");
1067+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec4_t, y) == 4, "vecmath vec3_t type member 'y' must be at offset 4");
1068+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec4_t, z) == 8, "vecmath vec3_t type member 'z' must be at offset 8");
1069+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(vec4_t, w) == 12, "vecmath vec4_t type member 'w' must be at offset 12");
1070+
1071+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat22_t, x) == 0, "vecmath mat22_t type member 'x' must be at offset 0");
1072+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat22_t, y) == 8, "vecmath mat22_t type member 'y' must be at offset 8");
1073+
1074+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat23_t, x) == 0, "vecmath mat23_t type member 'x' must be at offset 0");
1075+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat23_t, y) == 12, "vecmath mat23_t type member 'y' must be at offset 12");
1076+
1077+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat24_t, x) == 0, "vecmath mat24_t type member 'x' must be at offset 0");
1078+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat24_t, y) == 16, "vecmath mat24_t type member 'y' must be at offset 16");
1079+
1080+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat32_t, x) == 0, "vecmath mat32_t type member 'x' must be at offset 0");
1081+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat32_t, y) == 8, "vecmath mat32_t type member 'y' must be at offset 8");
1082+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat32_t, z) == 16, "vecmath mat32_t type member 'z' must be at offset 16");
1083+
1084+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat33_t, x) == 0, "vecmath mat33_t type member 'x' must be at offset 0");
1085+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat33_t, y) == 12, "vecmath mat33_t type member 'y' must be at offset 12");
1086+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat33_t, z) == 24, "vecmath mat33_t type member 'z' must be at offset 24");
1087+
1088+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat34_t, x) == 0, "vecmath mat34_t type member 'x' must be at offset 0");
1089+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat34_t, y) == 16, "vecmath mat34_t type member 'y' must be at offset 16");
1090+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat34_t, z) == 32, "vecmath mat34_t type member 'z' must be at offset 32");
1091+
1092+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat42_t, x) == 0, "vecmath mat42_t type member 'x' must be at offset 0");
1093+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat42_t, y) == 8, "vecmath mat42_t type member 'y' must be at offset 8");
1094+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat42_t, z) == 16, "vecmath mat42_t type member 'z' must be at offset 16");
1095+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat42_t, w) == 24, "vecmath mat42_t type member 'w' must be at offset 24");
1096+
1097+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat43_t, x) == 0, "vecmath mat43_t type member 'x' must be at offset 0");
1098+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat43_t, y) == 12, "vecmath mat43_t type member 'y' must be at offset 12");
1099+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat43_t, z) == 24, "vecmath mat43_t type member 'z' must be at offset 24");
1100+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat43_t, w) == 36, "vecmath mat43_t type member 'w' must be at offset 36");
1101+
1102+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat44_t, x) == 0, "vecmath mat44_t type member 'x' must be at offset 0");
1103+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat44_t, y) == 16, "vecmath mat44_t type member 'y' must be at offset 16");
1104+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat44_t, z) == 32, "vecmath mat44_t type member 'z' must be at offset 32");
1105+
VECMATH_STATIC_ASSERT(VECMATH_OFFSETOF(mat44_t, w) == 48, "vecmath mat44_t type member 'w' must be at offset 48");
1106+
1107+
/* Further, some tests assume the exact binary representation of the types. If
1108+
* the types had trailing elements after the required ones, like debug tags or
1109+
* whatever, those would be lost when new values are returned. The following
1110+
* static assertions ensure there is no hidden data in the structs which could
1111+
* interfere with tests. */
1112+
1113+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(vec2_t) == 8, "vecmath vec2_t type must be 8 bytes big exactly");
1114+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(vec3_t) == 12, "vecmath vec3_t type must be 12 bytes big exactly");
1115+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(vec4_t) == 16, "vecmath vec4_t type must be 16 bytes big exactly");
1116+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat22_t) == 16, "vecmath mat22_t type must be 16 bytes big exactly");
1117+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat23_t) == 24, "vecmath mat23_t type must be 24 bytes big exactly");
1118+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat24_t) == 32, "vecmath mat24_t type must be 32 bytes big exactly");
1119+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat32_t) == 24, "vecmath mat32_t type must be 24 bytes big exactly");
1120+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat33_t) == 36, "vecmath mat33_t type must be 36 bytes big exactly");
1121+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat34_t) == 48, "vecmath mat34_t type must be 48 bytes big exactly");
1122+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat42_t) == 32, "vecmath mat42_t type must be 32 bytes big exactly");
1123+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat43_t) == 48, "vecmath mat43_t type must be 48 bytes big exactly");
1124+
VECMATH_STATIC_ASSERT(VECMATH_SIZEOF(mat44_t) == 64, "vecmath mat44_t type must be 64 bytes big exactly");
10481125

10491126
// math defines
10501127

0 commit comments

Comments
 (0)