aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-01-11 06:32:45 -0800
committerChris Robinson <[email protected]>2018-01-11 06:32:45 -0800
commitf3c9bc114cb1d136fce4e790d6d2721430eb30dc (patch)
tree97d518d92f07360056ec28f090844f0bacc3ce59
parentff231b42ff82349d935861e7afcfd4e7a7917471 (diff)
Move the polymorphic/inheritance macros to a separate header
-rw-r--r--Alc/polymorphism.h108
-rw-r--r--OpenAL32/Include/alMain.h95
2 files changed, 109 insertions, 94 deletions
diff --git a/Alc/polymorphism.h b/Alc/polymorphism.h
new file mode 100644
index 00000000..b41ad64b
--- /dev/null
+++ b/Alc/polymorphism.h
@@ -0,0 +1,108 @@
+#ifndef POLYMORPHISM_H
+#define POLYMORPHISM_H
+
+/* Macros to declare inheriting types, and to (down-)cast and up-cast. */
+#define DERIVE_FROM_TYPE(t) t t##_parent
+#define STATIC_CAST(to, obj) (&(obj)->to##_parent)
+#ifdef __GNUC__
+#define STATIC_UPCAST(to, from, obj) __extension__({ \
+ static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
+ "Invalid upcast object from type"); \
+ (to*)((char*)(obj) - offsetof(to, from##_parent)); \
+})
+#else
+#define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
+#endif
+
+/* Defines method forwards, which call the given parent's (T2's) implementation. */
+#define DECLARE_FORWARD(T1, T2, rettype, func) \
+rettype T1##_##func(T1 *obj) \
+{ return T2##_##func(STATIC_CAST(T2, obj)); }
+
+#define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
+rettype T1##_##func(T1 *obj, argtype1 a) \
+{ return T2##_##func(STATIC_CAST(T2, obj), a); }
+
+#define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
+rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
+{ return T2##_##func(STATIC_CAST(T2, obj), a, b); }
+
+#define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
+rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
+{ return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
+
+/* Defines method thunks, functions that call to the child's method. */
+#define DECLARE_THUNK(T1, T2, rettype, func) \
+static rettype T1##_##T2##_##func(T2 *obj) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
+
+#define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
+static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
+
+#define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
+static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
+
+#define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
+static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
+
+#define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \
+static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); }
+
+/* Defines the default functions used to (de)allocate a polymorphic object. */
+#define DECLARE_DEFAULT_ALLOCATORS(T) \
+static void* T##_New(size_t size) { return al_malloc(16, size); } \
+static void T##_Delete(void *ptr) { al_free(ptr); }
+
+
+/* Helper to extract an argument list for virtual method calls. */
+#define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
+
+/* Call a "virtual" method on an object, with arguments. */
+#define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
+/* Call a "virtual" method on an object, with no arguments. */
+#define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
+
+
+/* Helper to extract an argument list for NEW_OBJ calls. */
+#define EXTRACT_NEW_ARGS(...) __VA_ARGS__); \
+ } \
+} while(0)
+
+/* Allocate and construct an object, with arguments. */
+#define NEW_OBJ(_res, T) do { \
+ _res = T##_New(sizeof(T)); \
+ if(_res) \
+ { \
+ memset(_res, 0, sizeof(T)); \
+ T##_Construct(_res, EXTRACT_NEW_ARGS
+/* Allocate and construct an object, with no arguments. */
+#define NEW_OBJ0(_res, T) do { \
+ _res = T##_New(sizeof(T)); \
+ if(_res) \
+ { \
+ memset(_res, 0, sizeof(T)); \
+ T##_Construct(_res EXTRACT_NEW_ARGS
+
+/* Destructs and deallocate an object. */
+#define DELETE_OBJ(obj) do { \
+ if((obj) != NULL) \
+ { \
+ V0((obj),Destruct)(); \
+ V0((obj),Delete)(); \
+ } \
+} while(0)
+
+
+/* Helper to get a type's vtable thunk for a child type. */
+#define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
+/* Helper to set an object's vtable thunk for a child type. Used when constructing an object. */
+#define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
+
+/* Helper to set an object's vtable for a type. */
+#define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable))
+
+#endif /* POLYMORPHISM_H */
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 617b5a64..7af7b4bb 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -21,6 +21,7 @@
#include "AL/alc.h"
#include "AL/alext.h"
+#include "polymorphism.h"
#include "static_assert.h"
#include "align.h"
#include "atomic.h"
@@ -286,100 +287,6 @@ static const union {
#define COUNTOF(x) (sizeof(x) / sizeof(0[x]))
-#define DERIVE_FROM_TYPE(t) t t##_parent
-#define STATIC_CAST(to, obj) (&(obj)->to##_parent)
-#ifdef __GNUC__
-#define STATIC_UPCAST(to, from, obj) __extension__({ \
- static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
- "Invalid upcast object from type"); \
- (to*)((char*)(obj) - offsetof(to, from##_parent)); \
-})
-#else
-#define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
-#endif
-
-#define DECLARE_FORWARD(T1, T2, rettype, func) \
-rettype T1##_##func(T1 *obj) \
-{ return T2##_##func(STATIC_CAST(T2, obj)); }
-
-#define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
-rettype T1##_##func(T1 *obj, argtype1 a) \
-{ return T2##_##func(STATIC_CAST(T2, obj), a); }
-
-#define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
-rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
-{ return T2##_##func(STATIC_CAST(T2, obj), a, b); }
-
-#define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
-rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
-{ return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
-
-
-#define GET_VTABLE1(T1) (&(T1##_vtable))
-#define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
-
-#define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
-#define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
-
-#define DECLARE_THUNK(T1, T2, rettype, func) \
-static rettype T1##_##T2##_##func(T2 *obj) \
-{ return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
-
-#define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
-static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
-{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
-
-#define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
-static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
-{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
-
-#define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
-static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
-{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
-
-#define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \
-static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \
-{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); }
-
-#define DECLARE_DEFAULT_ALLOCATORS(T) \
-static void* T##_New(size_t size) { return al_malloc(16, size); } \
-static void T##_Delete(void *ptr) { al_free(ptr); }
-
-/* Helper to extract an argument list for VCALL. Not used directly. */
-#define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
-
-/* Call a "virtual" method on an object, with arguments. */
-#define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
-/* Call a "virtual" method on an object, with no arguments. */
-#define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
-
-#define DELETE_OBJ(obj) do { \
- if((obj) != NULL) \
- { \
- V0((obj),Destruct)(); \
- V0((obj),Delete)(); \
- } \
-} while(0)
-
-
-#define EXTRACT_NEW_ARGS(...) __VA_ARGS__); \
- } \
-} while(0)
-
-#define NEW_OBJ(_res, T) do { \
- _res = T##_New(sizeof(T)); \
- if(_res) \
- { \
- memset(_res, 0, sizeof(T)); \
- T##_Construct(_res, EXTRACT_NEW_ARGS
-#define NEW_OBJ0(_res, T) do { \
- _res = T##_New(sizeof(T)); \
- if(_res) \
- { \
- memset(_res, 0, sizeof(T)); \
- T##_Construct(_res EXTRACT_NEW_ARGS
-
-
#ifdef __cplusplus
extern "C" {
#endif