#define SOD_CONVERT(cls, obj) ((cls *)sod_convert(cls##__class, (obj)))
+/* --- @SOD_INIT@ --- *
+ *
+ * Arguments: @cls@ = a class type name
+ * @p@ = pointer to storage to initialize
+ * @keys@ = a @KWARGS(...)@ keyword argument sequence
+ *
+ * Use: Initializes raw storage as an instance of @cls@.
+ */
+
+#define SOD_INIT(cls, p, keys) ((cls *)sod_init(cls##__class, (p), keys))
+
/* --- @SOD_DECL@ --- *
*
- * Arguments: @cls_@ = a class type name
- * @var_@ = a variable name
+ * Arguments: @cls@ = a class type name
+ * @var@ = a variable name
+ * @keys@ = a @KWARGS(...)@ keyword argument sequence
*
- * Use: Declare @var_@ as a pointer to an initialized instance of
- * @cls_@ with automatic lifetime.
+ * 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(cls_##__class->cls.imprint(&var_##__layout))
+#define SOD_DECL(cls, var, keys) \
+ struct cls##__ilayout var##__layout; \
+ cls *var = (cls *)sod_init(cls##__class, &var##__layout, keys)
/*----- Functions provided ------------------------------------------------*/
extern void *sod_convert(const SodClass */*cls*/, const void */*obj*/);
+/* --- @sod_init@, @sod_initv@ --- *
+ *
+ * Arguments: @const SodClass *cls@ = class object for new instance
+ * @void *p@ = pointer to storage for new instance
+ * @va_list ap, ...@ = initialization keyword arguments
+ *
+ * Returns: Pointer to the initialized instance.
+ *
+ * Use: Initializes an instance in pre-allocated storage, and returns
+ * a pointer to it.
+ *
+ * This function will imprint the storage, and then send an
+ * `initialize' message to the fresh instance containing the
+ * provided keyword arguments.
+ *
+ * It's usually convenient to use the macro @SOD_INIT@ rather
+ * than calling @sod_init@ directly.
+ */
+
+extern KWCALL void *sod_init(const SodClass */*cls*/, void */*p*/, ...);
+extern void *sod_initv(const SodClass */*cls*/, void */*p*/, va_list /*ap*/);
+
/*----- That's all, folks -------------------------------------------------*/
#ifdef __cplusplus