New feature: proper object lifecycle protocol; init and teardown fragments.
[sod] / lib / sod.h
index 185c6fb..8945810 100644 (file)
--- a/lib/sod.h
+++ b/lib/sod.h
 /* We're going to want to make use of this ourselves. */
 SOD__VARARGS_MACROS_PREAMBLE
 
+/* --- @SOD__IGNORE@ --- *
+ *
+ * Arguments:  @var@ = some variable name
+ *
+ * Use:                Suppress any warning that @var@ isn't used.
+ */
+
+#define SOD__IGNORE(var) ((void)(var))
+
 /* --- @SOD__CAR@ --- *
  *
  * Arguments:  @...@ = a nonempty list of arguments
@@ -238,6 +247,18 @@ struct sod_chain {
 
 #define SOD_INIT(cls, p, keys) ((cls *)sod_init(cls##__class, (p), keys))
 
+/* --- @SOD_MAKE@ --- *
+ *
+ * Arguments:  @cls@ = a class type name
+ *             @keys@ = a @KWARGS(...)@ keyword argument sequence
+ *
+ * Use:                Allocates (using @malloc@) eand initializes storage to be an
+ *             instance of @cls@.  Returns a null pointer if allocation
+ *             fails.  Use @sod_destroy@ to release the instance.
+ */
+
+#define SOD_MAKE(cls, keys) ((cls *)sod_make(cls##__class, keys))
+
 /* --- @SOD_DECL@ --- *
  *
  * Arguments:  @cls@ = a class type name
@@ -313,6 +334,73 @@ extern void *sod_convert(const SodClass */*cls*/, const void */*obj*/);
 extern KWCALL void *sod_init(const SodClass */*cls*/, void */*p*/, ...);
 extern void *sod_initv(const SodClass */*cls*/, void */*p*/, va_list /*ap*/);
 
+/* --- @sod_make@, @sod_makev@ --- *
+ *
+ * Arguments:  @const SodClass *cls@ = class object for new instance
+ *             @va_list ap, ...@ = initialization keyword arguments
+ *
+ * Returns:    Pointer to the newly-allocated initialized instance, or null.
+ *
+ * Use:                Allocates storage for a new instance, initializes it, and
+ *             returns a pointer to it.  If allocation fails, a null pointer
+ *             is returned instead.
+ *
+ *             This function will allocate the storage using @malloc@, and
+ *             then initialize it as for @sod_init@.
+ *
+ *             It's usually convenient to use the macro @SOD_MAKE@ rather
+ *             than calling @sod_make@ directly.
+ *
+ *             (This function is not available in freestanding environments
+ *             lacking @malloc@ and @free@.)
+ */
+
+extern KWCALL void *sod_make(const SodClass */*cls*/, ...);
+extern void *sod_makev(const SodClass */*cls*/, va_list /*ap*/);
+
+/* --- @sod_teardown@ --- *
+ *
+ * Arguments:  @void *p@ = pointer to an instance to be torn down
+ *
+ * Returns:    Zero if the object is torn down; nonzero if it refused for
+ *             some reason.
+ *
+ * Use:                Invokes the instance's `teardown' method to release any held
+ *             resources.
+ *
+ *             If this function returns nonzero, then the object is still
+ *             active, and may still hold important resources.  This is not
+ *             intended to be a failure condition: failures in teardown are
+ *             usually unrecoverable (or very hard to recover from) and
+ *             should probably cause the program to abort.  A refusal, on
+ *             the other hand, means that the object is still live and
+ *             shouldn't be deallocated, but that this is a normal situation
+ *             and the caller shouldn't worry about it.
+ */
+
+extern int sod_teardown(void */*p*/);
+
+/* --- @sod_destroy@ --- *
+ *
+ * Arguments:  @void *p@ = pointer to an instance to be torn down, or null
+ *
+ * Returns:    Zero if the object was freed; nonzero if it refused for some
+ *             reason.
+ *
+ * Use:                Invokes the instance's `teardown' method to release any held
+ *             resources, and then calls @free@ to release the instance's
+ *             storage.  See @sod_teardown@ for details, especially
+ *             regarding the return value's meaning.
+ *
+ *             If @p@ is null, then this function does nothing except
+ *             returns zero.
+ *
+ *             (This function is not available in freestanding environments
+ *             lacking @malloc@ and @free@.)
+ */
+
+extern int sod_destroy(void */*p*/);
+
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus