@@@ fltfmt mess
[mLib] / mem / alloc.h
index 2349181..8a5c364 100644 (file)
 
 /*----- Functions and macros ----------------------------------------------*/
 
-/* --- @x_alloc@ --- *
+/* --- @x_alloc@, @x_allocv@ --- *
  *
  * Arguments:  @arena *a@ = pointer to underlying arena
- *             @size_t sz@ = size of block to allocate
+ *             @size_t n@ = number of elements to allocate (for @x_allocv@)
+ *             @size_t sz@ = size of elements to allocate
  *
  * Returns:    Pointer to allocated block.
  *
- * Use:                Allocates memory.  If there's not enough memory, the
- *             exception @EXC_NOMEM@ is thrown.
+ * Use:                The @x_allocv@ function allocates memory for @n@ elements of
+ *             @sz@ bytes each (or, perhaps, %%\emph{vice versa}).  The
+ *             @x_alloc@ function is the same, but with @n@ fixed equal
+ *             to 1.  If there's not enough memory, the exception
+ *             @EXC_NOMEM@ is thrown.
  */
 
 extern void *x_alloc(arena */*a*/, size_t /*sz*/);
+extern void *x_allocv(arena */*a*/, size_t /*n*/, size_t /*sz*/);
+
+/* --- @X_NEW@, @X_NEWV@ --- *
+ *
+ * Arguments:  @type *p@ = a pointer to allocate
+ *             @arena *a@ = pointer to underlying arena
+ *             @size_t n@ = number of elements
+ *
+ * Returns:    ---
+ *
+ * Use:                Set @p@ to point to a freshly allocate block large enough for
+ *             @n@ elements each of the type pointed to by @p@.
+ */
+
+#define X_NEW(p, a) do { (p) = x_alloc((a), sizeof(*(p))); } while (0)
+#define X_NEWV(p, a, n)                                                        \
+       do { (p) = x_allocv((a), (n), sizeof(*(p))); } while (0)
 
 /* --- @x_strdup@ --- *
  *
@@ -69,22 +90,51 @@ extern void *x_alloc(arena */*a*/, size_t /*sz*/);
 
 extern char *x_strdup(arena */*a*/, const char */*s*/);
 
-/* --- @x_realloc@ --- *
+/* --- @x_realloc@, @x_reallocv@ --- *
  *
  * Arguments:  @arena *a@ = pointer to underlying arena
  *             @void *p@ = pointer to a block of memory
- *             @size_t sz@ = new size desired for the block
- *             @size_t osz@ = size of the old block
+ *             @size_t n@ = new number of elements (for @x_reallocv@)
+ *             @size_t on@ = old  number of elements (for @x_reallocv@)
+ *             @size_t sz@ = size of elements (for @x_reallocv@) or new
+ *                     block size (for @x_realloc@)
+ *             @size_t osz@ = size of the old block (for @x_realloc@)
  *
  * Returns:    Pointer to the resized memory block (which is almost
  *             certainly not in the same place any more).
  *
  * Use:                Resizes a memory block.  If there's not enough memory, the
  *             exception @EXC_NOMEM@ is thrown.
+ *
+ *             The @x_reallocv@ function adjusts a block which currently has
+ *             space for @on@ elements each of size @sz@, so that it now has
+ *             enough space for @n@ elements, preserving the initial @min(n,
+ *             on)@ elements.  The @x_realloc@ function is the same, but
+ *             with @sz@ fixed equal to 1, and @n@ and @on@ renamed to @sz@
+ *             and @osz@ for historical reasons.
  */
 
 extern void *x_realloc(arena */*a*/, void */*p*/,
                       size_t /*sz*/, size_t /*osz*/);
+extern void *x_reallocv(arena */*a*/, void */*p*/,
+                       size_t /*n*/, size_t /*on*/, size_t /*sz*/);
+
+/* --- @X_RENEWV@ --- *
+ *
+ * Arguments:  @type *p@ = a pointer to allocate
+ *             @arena *a@ = pointer to underlying arena
+ *             @size_t n, on@ = new and existing numbers of elements
+ *
+ * Returns:    ---
+ *
+ * Use:                Adjust @p@ to point to a new block of memory with space for
+ *             @n@ elements of the type pointed to by @p@, on the assumption
+ *             that @p@ is either null or currently points to a block with
+ *             space for @on@ elements.
+ */
+
+#define X_RENEWV(p, a, n, on)                                          \
+       do { (p) = x_reallocv((a), (p), (n), (on), sizeof(*(p))); } while (0)
 
 /* --- @x_free@ --- *
  *
@@ -101,18 +151,36 @@ extern void x_free(arena */*a*/, void */*p*/);
 
 /*----- Old functions for the standard arena ------------------------------*/
 
-/* --- @xmalloc@ --- *
+/* --- @xmalloc@, @xmallocv@ --- *
  *
- * Arguments:  @size_t sz@ = size of block to allocate
+ * Arguments:  @size_t n@ = number of elements to allocate (for @xmallocv@)
+ *             @size_t sz@ = size of block to allocate
  *
  * Returns:    Pointer to allocated block.
  *
- * Use:                Allocates memory.  If there's not enough memory, the
- *             exception @EXC_NOMEM@ is thrown.
+ * Use:                Allocates memory for @n@ elements each of size @sz@.  For
+ *             @xmalloc@, @n@ is fixed equal to 1.  If there's not enough
+ *             memory, the exception @EXC_NOMEM@ is thrown.
  */
 
 extern void *xmalloc(size_t /*sz*/);
+extern void *xmallocv(size_t /*n*/, size_t /*sz*/);
 #define xmalloc(sz) x_alloc(arena_global, (sz))
+#define xmallocv(n, sz) x_allocv(arena_global, (n), (sz))
+
+/* --- @XNEW@, @XNEWV@ --- *
+ *
+ * Arguments:  @type *p@ = a pointer to allocate
+ *             @size_t n@ = number of elements
+ *
+ * Returns:    ---
+ *
+ * Use:                Set @p@ to point to a freshly allocate block large enough for
+ *             @n@ elements each of the type pointed to by @p@.
+ */
+
+#define XNEW(p) X_NEW(p, arena_global);
+#define XNEWV(p, n) X_NEWV(p, arena_global, n);
 
 /* --- @xstrdup@ --- *
  *
@@ -128,21 +196,50 @@ extern void *xmalloc(size_t /*sz*/);
 extern char *xstrdup(const char */*s*/);
 #define xstrdup(p) x_strdup(arena_global, (p))
 
-/* --- @xrealloc@ --- *
+/* --- @xrealloc@, @xreallocv@ --- *
  *
  * Arguments:  @void *p@ = pointer to a block of memory
- *             @size_t sz@ = new size desired for the block
- *             @size_t osz@ = size of the old block
+ *             @size_t n@ = new number of elements (for @xreallocv@)
+ *             @size_t on@ = old  number of elements (for @xreallocv@)
+ *             @size_t sz@ = size of elements (for @xreallocv@) or new
+ *                     block size (for @xrealloc@)
+ *             @size_t osz@ = size of the old block (for @xrealloc@)
  *
  * Returns:    Pointer to the resized memory block (which is almost
  *             certainly not in the same place any more).
  *
  * Use:                Resizes a memory block.  If there's not enough memory, the
  *             exception @EXC_NOMEM@ is thrown.
+ *
+ *             The @xreallocv@ function adjusts a block which currently has
+ *             space for @on@ elements each of size @sz@, so that it now has
+ *             enough space for @n@ elements, preserving the initial @min(n,
+ *             on)@ elements.  The @xrealloc@ function is the same, but
+ *             with @sz@ fixed equal to 1, and @n@ and @on@ renamed to @sz@
+ *             and @osz@ for historical reasons.
  */
 
 extern void *xrealloc(void */*p*/, size_t /*sz*/, size_t /*osz*/);
+extern void *xreallocv(void */*p*/,
+                      size_t /*n*/, size_t /*on*/, size_t /*sz*/);
 #define xrealloc(p, sz, osz) x_realloc(arena_global, (p), (sz), (osz))
+#define xreallocv(p, sz, osz, n) x_reallocv(arena_global,              \
+                                           (p), (sz), (osz), (n))
+
+/* --- @XRENEWV@ --- *
+ *
+ * Arguments:  @type *p@ = a pointer to allocate
+ *             @size_t n, on@ = new and existing numbers of elements
+ *
+ * Returns:    ---
+ *
+ * Use:                Adjust @p@ to point to a new block of memory with space for
+ *             @n@ elements of the type pointed to by @p@, on the assumption
+ *             that @p@ is either null or currently points to a block with
+ *             space for @on@ elements.
+ */
+
+#define XRENEWV(p, n, on) X_RENEWV((p), arena_global, (n), (on))
 
 /* --- @xfree@ --- *
  *