lib/sod.h: Arrange that `SOD_XCHAIN' returns `void *'.
[sod] / lib / sod.h
index 594e343..efac06b 100644 (file)
--- a/lib/sod.h
+++ b/lib/sod.h
@@ -53,7 +53,7 @@ struct sod_vtable {
  * these.
  */
 struct sod_instance {
-  struct sod_vtable *_vt;              /* Pointer to (chain's) vtable */
+  const struct sod_vtable *_vt;                /* Pointer to (chain's) vtable */
 };
 
 /* Information about a particular chain of superclasses.  In each class,
@@ -76,14 +76,15 @@ struct sod_chain {
  * Arguments:  @chead@ = nickname of target chain's head
  *             @obj@ = pointer to an instance chain
  *
- * Returns:    Pointer to target chain, as a @char *@.
+ * Returns:    Pointer to target chain, as a @void *@.
  *
  * Use:                Utility for implementing cross-chain upcasts.  It's probably
  *             not that clever to use this macro directly; it's used to make
  *             the automatically-generated upcast macros more palatable.
  */
 
-#define SOD_XCHAIN(chead, obj) ((char *)(obj) + (obj)->_vt->_off_##chead)
+#define SOD_XCHAIN(chead, obj)                                         \
+  ((void *)((char *)(obj) + (obj)->_vt->_off_##chead))
 
 /* --- @SOD_OFFSETDIFF@ --- *
  *
@@ -124,6 +125,18 @@ struct sod_chain {
   ((struct cls##__ilayout *)                                           \
    ((char *)(obj) - offsetof(struct cls##__ilayout, chead)))
 
+/* --- @SOD_CAR@ --- *
+ *
+ * Arguments:  @...@ = a nonempty list of arguments
+ *
+ * Returns:    The first argument only.
+ */
+
+#if __STDC_VERSION__ >= 199901
+#  define SOD_CAR(...) SOD__CARx(__VA_LIST__, _)
+#  define SOD__CARx(a, ...) a
+#endif
+
 /*----- Utility macros ----------------------------------------------------*/
 
 /* --- @SOD_CLASSOF@ --- *
@@ -168,6 +181,19 @@ struct sod_chain {
 
 #define SOD_CONVERT(cls, obj) ((cls *)sod_convert(cls##__class, (obj)))
 
+/* --- @SOD_DECL@ --- *
+ *
+ * Arguments:  @cls_@ = a class type name
+ *             @var_@ = a variable name
+ *
+ * Use:                Declare @var_@ as a pointer to an initialized instance of
+ *             @cls_@ with automatic lifetime.
+ */
+
+#define SOD_DECL(cls_, var_)                                           \
+  struct cls_##__ilayout var_##__layout;                               \
+  cls_ *var_ = cls_##__class->cls.init(&var_##__layout)
+
 /*----- Functions provided ------------------------------------------------*/
 
 /* --- @sod_subclassp@ --- *