From 7ab7d7d5b836d2595c5dc2c6db90c489f6768246 Mon Sep 17 00:00:00 2001
From: 3gg <3gg@shellblade.net>
Date: Sun, 16 Jul 2023 17:39:54 -0700
Subject: Fix mem and mempool iteration.

---
 mem/include/mem.h           | 46 +++++++++++++++++++++++++--------------------
 mem/test/mem_test.c         |  4 ++--
 mempool/include/mempool.h   | 44 ++++++++++++++++++++++---------------------
 mempool/test/mempool_test.c |  2 +-
 4 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/mem/include/mem.h b/mem/include/mem.h
index 69f426f..b3d9157 100644
--- a/mem/include/mem.h
+++ b/mem/include/mem.h
@@ -19,19 +19,24 @@
 #include <stdint.h>
 
 /// Define a typed memory allocator backed by a statically-allocated array.
-#define DEF_MEM(MEM, TYPE, NUM_BLOCKS) \
-  typedef struct MEM {                 \
-    Memory mem;                        \
-    Chunk  chunks[NUM_BLOCKS];         \
-    TYPE   blocks[NUM_BLOCKS];         \
+#define DEF_MEM(MEM, TYPE, NUM_BLOCKS)                        \
+  typedef struct MEM {                                        \
+    Memory mem;                                               \
+    Chunk  chunks[NUM_BLOCKS];                                \
+    TYPE   blocks[NUM_BLOCKS];                                \
+    /* For uniformity with the dynamically-allocated pool. */ \
+    TYPE* object;                                             \
   } MEM;
 
 /// Define a typed memory allocator backed by a dynamically-allocated array.
-#define DEF_MEM_DYN(MEM, TYPE) \
-  typedef struct MEM {         \
-    Memory mem;                \
-    Chunk* chunks;             \
-    TYPE*  blocks;             \
+#define DEF_MEM_DYN(MEM, TYPE)                                               \
+  typedef struct MEM {                                                       \
+    Memory mem;                                                              \
+    Chunk* chunks;                                                           \
+    TYPE*  blocks;                                                           \
+    /* Does not point anywhere. Storing a pointer here so that we can recall \
+     * the type. */                                                          \
+    TYPE* object;                                                            \
   } MEM;
 
 /// Initialize a statically-backed memory allocator.
@@ -73,7 +78,7 @@
 /// Return a pointer to a chunk given the chunk's handle.
 /// The chunk must have been allocated.
 #define mem_get_chunk(MEM, HANDLE) \
-  ((__typeof__((MEM)->blocks[0])*)mem_get_chunk_(&(MEM)->mem, HANDLE))
+  ((__typeof__((MEM)->object[0])*)mem_get_chunk_(&(MEM)->mem, HANDLE))
 
 /// Get the handle to the given chunk.
 #define mem_get_chunk_handle(MEM, CHUNK_PTR) \
@@ -87,15 +92,16 @@
 /// The caller can use 'i' as the index of the current chunk.
 ///
 /// It is valid to mem_free() the chunk at each step of the iteration.
-#define mem_foreach(MEM, ITER, BODY)                          \
-  size_t i = 0;                                               \
-  do {                                                        \
-    if ((MEM)->chunks[i].used) {                              \
-      __typeof__((MEM)->blocks[0])* ITER = &(MEM)->blocks[i]; \
-      (void)ITER;                                             \
-      BODY;                                                   \
-    }                                                         \
-    i = (MEM)->chunks[i].next;                                \
+#define mem_foreach(MEM, ITER, BODY)                                \
+  size_t i = 0;                                                     \
+  do {                                                              \
+    if ((MEM)->mem.chunks[i].used) {                                \
+      __typeof__((MEM)->object[0])* ITER =                          \
+          &(((__typeof__((MEM)->object[0])*)(MEM)->mem.blocks))[i]; \
+      (void)ITER;                                                   \
+      BODY;                                                         \
+    }                                                               \
+    i = (MEM)->chunks[i].next;                                      \
   } while (i);
 
 // -----------------------------------------------------------------------------
diff --git a/mem/test/mem_test.c b/mem/test/mem_test.c
index 6ab4c7c..2f242c3 100644
--- a/mem/test/mem_test.c
+++ b/mem/test/mem_test.c
@@ -4,7 +4,7 @@
 
 #define NUM_BLOCKS 10
 
-DEF_MEM(test_mem, int, NUM_BLOCKS);
+DEF_MEM(test_mem, int, NUM_BLOCKS)
 
 static int count(test_mem* mem) {
   int count = 0;
@@ -27,7 +27,7 @@ TEST_CASE(mem_create) {
 // Create a dynamically-backed allocator.
 TEST_CASE(mem_create_dyn) {
   DEF_MEM_DYN(dyn_mem, int);
-  
+
   dyn_mem mem;
   mem_make_dyn(&mem, NUM_BLOCKS, sizeof(int));
 }
diff --git a/mempool/include/mempool.h b/mempool/include/mempool.h
index 8251a70..23786b3 100644
--- a/mempool/include/mempool.h
+++ b/mempool/include/mempool.h
@@ -19,19 +19,22 @@
 #include <stdint.h>
 
 /// Define a statically-allocated, typed pool of the given number of blocks.
-#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS) \
-  typedef struct POOL {                     \
-    mempool   pool;                         \
-    BlockInfo block_info[NUM_BLOCKS];       \
-    TYPE      blocks[NUM_BLOCKS];           \
+#define DEF_MEMPOOL(POOL, TYPE, NUM_BLOCKS)                   \
+  typedef struct POOL {                                       \
+    mempool   pool;                                           \
+    BlockInfo block_info[NUM_BLOCKS];                         \
+    TYPE      blocks[NUM_BLOCKS];                             \
+    /* For uniformity with the dynamically-allocated pool. */ \
+    TYPE* object;                                             \
   } POOL;
 
 /// Define a dynamically-allocated, typed pool.
-#define DEF_MEMPOOL_DYN(POOL, TYPE) \
-  typedef struct POOL {             \
-    mempool    pool;                \
-    BlockInfo* block_info;          \
-    TYPE*      blocks;              \
+#define DEF_MEMPOOL_DYN(POOL, TYPE)                                          \
+  typedef struct POOL {                                                      \
+    mempool pool;                                                            \
+    /* Does not point anywhere. Storing a pointer here so that we can recall \
+     * the type. */                                                          \
+    TYPE* object;                                                            \
   } POOL;
 
 /// Initialize a statically-allocated pool.
@@ -74,7 +77,7 @@
 /// Return the ith block.
 /// The block must have been allocated.
 #define mempool_get_block(POOL, INDEX) \
-  ((__typeof__((POOL)->blocks[0])*)mempool_get_block_(&(POOL)->pool, INDEX))
+  ((__typeof__((POOL)->object[0])*)mempool_get_block_(&(POOL)->pool, INDEX))
 
 /// Get the index to the given block.
 #define mempool_get_block_index(POOL, BLOCK_PTR) \
@@ -88,16 +91,15 @@
 /// The caller can use 'i' as the index of the current block.
 ///
 /// It is valid to mempool_free() the object at each step of the iteration.
-#define mempool_foreach(POOL, ITER, BODY)                                    \
-  for (size_t i = 0;                                                         \
-       i < (sizeof((POOL)->blocks) / sizeof(__typeof__((POOL)->blocks[0]))); \
-       ++i) {                                                                \
-    if (!(POOL)->block_info[i].used) {                                       \
-      continue;                                                              \
-    }                                                                        \
-    __typeof__((POOL)->blocks[0])* ITER = &(POOL)->blocks[i];                \
-    (void)ITER;                                                              \
-    BODY;                                                                    \
+#define mempool_foreach(POOL, ITER, BODY)                            \
+  for (size_t i = 0; i < (POOL)->pool.num_blocks; ++i) {             \
+    if (!(POOL)->pool.block_info[i].used) {                          \
+      continue;                                                      \
+    }                                                                \
+    __typeof__((POOL)->object[0])* ITER =                            \
+        &(((__typeof__((POOL)->object[0])*)(POOL)->pool.blocks))[i]; \
+    (void)ITER;                                                      \
+    BODY;                                                            \
   }
 
 // -----------------------------------------------------------------------------
diff --git a/mempool/test/mempool_test.c b/mempool/test/mempool_test.c
index e6c24a4..d5ed1ea 100644
--- a/mempool/test/mempool_test.c
+++ b/mempool/test/mempool_test.c
@@ -4,7 +4,7 @@
 
 #define NUM_BLOCKS 10
 
-DEF_MEMPOOL(test_pool, int, NUM_BLOCKS);
+DEF_MEMPOOL(test_pool, int, NUM_BLOCKS)
 
 static int count(test_pool* pool) {
   int count = 0;
-- 
cgit v1.2.3