summaryrefslogtreecommitdiff
path: root/cycle.c
diff options
context:
space:
mode:
authornoodle <shawtynoodle@gmail.com>2023-07-10 15:40:08 +0300
committernoodle <shawtynoodle@gmail.com>2023-07-10 15:40:08 +0300
commitb7ac144cd2d242791938b51569effb7a1378a332 (patch)
tree0db39dc6d72a96697707c662c32f4dcdb99372b7 /cycle.c
parent35eacac40f265aad47bf25d10f3ecd3670b79b2f (diff)
Add files
Diffstat (limited to 'cycle.c')
-rw-r--r--cycle.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/cycle.c b/cycle.c
new file mode 100644
index 0000000..6bdf994
--- /dev/null
+++ b/cycle.c
@@ -0,0 +1,77 @@
+#include <stddef.h> // for size_t
+#include <stdlib.h> // for malloc() and free()
+#include <assert.h>
+#include "utils.h"
+#include "cycle.h"
+
+/* cycling iterable */
+struct Cycle {
+ const void *base;
+ size_t i;
+ size_t memb_n;
+ size_t memb_size;
+};
+
+/*
+ * cycle_new: create a new cycle of array startinng at 'base' with memb_n
+ * elements each of size 'memb_size'
+ */
+struct Cycle *
+cycle_new(const void *base, size_t memb_n, size_t memb_size)
+{
+ assert(base != NULL);
+ assert(memb_n > 0);
+ assert(memb_size > 0);
+ struct Cycle *cycle = malloc(sizeof *cycle);
+
+ if (cycle == NULL) {
+ return NULL;
+ }
+ cycle->base = base;
+ cycle->i = 0;
+ cycle->memb_n = memb_n;
+ cycle->memb_size = memb_size;
+ return cycle;
+}
+
+/* cycle_free: free memmory used by cycle */
+void
+cycle_free(struct Cycle *cycle)
+{
+ assert(cycle != NULL);
+ free(cycle);
+}
+
+/* cycle_index: get index of current element of cycle */
+size_t
+cycle_index(struct Cycle *cycle)
+{
+ assert(cycle != NULL);
+ return cycle->i;
+}
+
+/* cycle_current: get current element of cycle */
+const void *
+cycle_current(struct Cycle *cycle)
+{
+ assert(cycle != NULL);
+ return (const char *)cycle->base + cycle->memb_size*cycle->i;
+}
+
+/* cycle_next: point cycle to next element and return it */
+const void *
+cycle_next(struct Cycle *cycle)
+{
+ assert(cycle != NULL);
+ cycle->i = (cycle->i >= cycle->memb_n-1) ? 0 : cycle->i+1;
+ return cycle_current(cycle);
+}
+
+/* cycle_prev: point cycle to previous elemetn and return it */
+const void *
+cycle_prev(struct Cycle *cycle)
+{
+ assert(cycle != NULL);
+ cycle->i = (cycle->i <= 0) ? cycle->memb_n-1 : cycle->i-1;
+ return cycle_current(cycle);
+}