Changed the name of two functions to be more consistent
This commit is contained in:
1 parent
5177ad9a8d
commit
12b68e3b36
4 files changed
+824
-824
No files matched your search
+1
-1
@@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "../../src/macro_collections.h"
|
||||
#include "../src/macro_collections.h"
|
||||
|
||||
// Create containers to use only in this file
|
||||
CONTAINER_GENERATE(LIST, PUBLIC, l, list, static, , int)
|
||||
|
||||
@@ -98,7 +98,7 @@ int main(void)
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
il_insert_if(list, i, list->count, i % 2 == 0);
|
||||
il_push_if(list, i, list->count, i % 2 == 0);
|
||||
}
|
||||
|
||||
// Print all even numbers
|
||||
|
||||
+493
-493
@@ -63,500 +63,500 @@
|
||||
}; \
|
||||
\
|
||||
/* HEADER ********************************************************************/
|
||||
#define LINKEDLIST_GENERATE_HEADER(PFX, SNAME, FMOD, K, T) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_node_s SNAME##_node; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(void); \
|
||||
FMOD void PFX##_free(SNAME *_list_); \
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, T element); \
|
||||
FMOD bool PFX##_push(SNAME *_list_, T element, size_t index); \
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, T element); \
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index); \
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_); \
|
||||
FMOD bool PFX##_insert_if(SNAME *_list_, T element, size_t index, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_list_, size_t index, bool condition); \
|
||||
FMOD T PFX##_back(SNAME *_list_); \
|
||||
FMOD T PFX##_get(SNAME *_list_, size_t index); \
|
||||
FMOD T PFX##_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_empty(SNAME *_list_); \
|
||||
FMOD size_t PFX##_count(SNAME *_list_); \
|
||||
\
|
||||
FMOD SNAME##_node *PFX##_new_node(SNAME *_owner_, T element); \
|
||||
FMOD SNAME##_node *PFX##_get_node(SNAME *_list_, size_t index); \
|
||||
FMOD bool PFX##_insert_nxt(SNAME##_node *node, T element); \
|
||||
FMOD bool PFX##_insert_prv(SNAME##_node *node, T element); \
|
||||
FMOD bool PFX##_remove_nxt(SNAME##_node *node); \
|
||||
FMOD bool PFX##_remove_cur(SNAME##_node *node); \
|
||||
FMOD bool PFX##_remove_prv(SNAME##_node *node); \
|
||||
\
|
||||
FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index); \
|
||||
\
|
||||
#define LINKEDLIST_GENERATE_HEADER(PFX, SNAME, FMOD, K, T) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_node_s SNAME##_node; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(void); \
|
||||
FMOD void PFX##_free(SNAME *_list_); \
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, T element); \
|
||||
FMOD bool PFX##_push(SNAME *_list_, T element, size_t index); \
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, T element); \
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index); \
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_); \
|
||||
FMOD bool PFX##_push_if(SNAME *_list_, T element, size_t index, bool condition); \
|
||||
FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition); \
|
||||
FMOD T PFX##_back(SNAME *_list_); \
|
||||
FMOD T PFX##_get(SNAME *_list_, size_t index); \
|
||||
FMOD T PFX##_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_empty(SNAME *_list_); \
|
||||
FMOD size_t PFX##_count(SNAME *_list_); \
|
||||
\
|
||||
FMOD SNAME##_node *PFX##_new_node(SNAME *_owner_, T element); \
|
||||
FMOD SNAME##_node *PFX##_get_node(SNAME *_list_, size_t index); \
|
||||
FMOD bool PFX##_insert_nxt(SNAME##_node *node, T element); \
|
||||
FMOD bool PFX##_insert_prv(SNAME##_node *node, T element); \
|
||||
FMOD bool PFX##_remove_nxt(SNAME##_node *node); \
|
||||
FMOD bool PFX##_remove_cur(SNAME##_node *node); \
|
||||
FMOD bool PFX##_remove_prv(SNAME##_node *node); \
|
||||
\
|
||||
FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define LINKEDLIST_GENERATE_SOURCE(PFX, SNAME, FMOD, K, T) \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(void) \
|
||||
{ \
|
||||
SNAME *_list_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_list_) \
|
||||
return NULL; \
|
||||
\
|
||||
_list_->count = 0; \
|
||||
_list_->head = NULL; \
|
||||
_list_->tail = NULL; \
|
||||
\
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_list_) \
|
||||
{ \
|
||||
SNAME##_node *scan = _list_->head; \
|
||||
while (_list_->head != NULL) \
|
||||
{ \
|
||||
_list_->head = _list_->head->next; \
|
||||
free(scan); \
|
||||
scan = _list_->head; \
|
||||
} \
|
||||
free(_list_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, T element) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_new_node(_list_, element); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
{ \
|
||||
_list_->head = node; \
|
||||
_list_->tail = node; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
node->next = _list_->head; \
|
||||
_list_->head->prev = node; \
|
||||
_list_->head = node; \
|
||||
} \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_list_, T element, size_t index) \
|
||||
{ \
|
||||
if (index > _list_->count) \
|
||||
return false; \
|
||||
\
|
||||
if (index == 0) \
|
||||
{ \
|
||||
return PFX##_push_front(_list_, element); \
|
||||
} \
|
||||
else if (index == _list_->count) \
|
||||
{ \
|
||||
return PFX##_push_back(_list_, element); \
|
||||
} \
|
||||
\
|
||||
SNAME##_node *node = PFX##_new_node(_list_, element); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *scan = PFX##_get_node(_list_, index - 1); \
|
||||
\
|
||||
node->next = scan->next; \
|
||||
node->prev = scan; \
|
||||
node->next->prev = node; \
|
||||
node->prev->next = node; \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, T element) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_new_node(_list_, element); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
{ \
|
||||
_list_->head = node; \
|
||||
_list_->tail = node; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
node->prev = _list_->tail; \
|
||||
_list_->tail->next = node; \
|
||||
_list_->tail = node; \
|
||||
} \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *node = _list_->head; \
|
||||
_list_->head = _list_->head->next; \
|
||||
\
|
||||
free(node); \
|
||||
\
|
||||
if (_list_->head == NULL) \
|
||||
_list_->tail = NULL; \
|
||||
else \
|
||||
_list_->head->prev = NULL; \
|
||||
\
|
||||
_list_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
if (index == 0) \
|
||||
{ \
|
||||
return PFX##_pop_front(_list_); \
|
||||
} \
|
||||
else if (index == _list_->count - 1) \
|
||||
{ \
|
||||
return PFX##_pop_back(_list_); \
|
||||
} \
|
||||
\
|
||||
SNAME##_node *node = PFX##_get_node(_list_, index); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
node->next->prev = node->prev; \
|
||||
node->prev->next = node->next; \
|
||||
\
|
||||
free(node); \
|
||||
\
|
||||
_list_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *node = _list_->tail; \
|
||||
_list_->tail = _list_->tail->prev; \
|
||||
\
|
||||
free(node); \
|
||||
\
|
||||
if (_list_->tail == NULL) \
|
||||
_list_->head = NULL; \
|
||||
else \
|
||||
_list_->tail->next = NULL; \
|
||||
\
|
||||
_list_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_list_, T element, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_list_, element, index); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_if(SNAME *_list_, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_list_, index); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->head->data; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_get(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return 0; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
SNAME##_node *scan = PFX##_get_node(_list_, index); \
|
||||
\
|
||||
if (scan == NULL) \
|
||||
return 0; \
|
||||
\
|
||||
return scan->data; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->tail->data; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_nxt(SNAME##_node *node, T element) \
|
||||
{ \
|
||||
SNAME##_node *new_node = PFX##_new_node(node->owner, element); \
|
||||
\
|
||||
if (!new_node) \
|
||||
return false; \
|
||||
\
|
||||
new_node->next = node->next; \
|
||||
if (node->next != NULL) \
|
||||
node->next->prev = new_node; \
|
||||
else \
|
||||
node->owner->tail = new_node; \
|
||||
\
|
||||
new_node->prev = node; \
|
||||
node->next = new_node; \
|
||||
\
|
||||
node->owner->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_prv(SNAME##_node *node, T element) \
|
||||
{ \
|
||||
SNAME##_node *new_node = PFX##_new_node(node->owner, element); \
|
||||
\
|
||||
if (!new_node) \
|
||||
return false; \
|
||||
\
|
||||
new_node->prev = node->prev; \
|
||||
if (node->prev != NULL) \
|
||||
node->prev->next = new_node; \
|
||||
else \
|
||||
node->owner->head = new_node; \
|
||||
\
|
||||
new_node->next = node; \
|
||||
node->prev = new_node; \
|
||||
\
|
||||
node->owner->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_nxt(SNAME##_node *node) \
|
||||
{ \
|
||||
if (node->next == NULL) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *tmp = node->next; \
|
||||
\
|
||||
if (node->next != NULL) \
|
||||
{ \
|
||||
node->next = node->next->next; \
|
||||
node->next->prev = node; \
|
||||
} \
|
||||
else \
|
||||
node->owner->tail = node; \
|
||||
\
|
||||
node->owner->count--; \
|
||||
\
|
||||
free(tmp); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_cur(SNAME##_node *node) \
|
||||
{ \
|
||||
if (node->prev != NULL) \
|
||||
node->prev->next = node->next; \
|
||||
else \
|
||||
node->owner->head = node->next; \
|
||||
\
|
||||
if (node->next != NULL) \
|
||||
node->next->prev = node->prev; \
|
||||
else \
|
||||
node->owner->tail = node->prev; \
|
||||
\
|
||||
node->owner->count--; \
|
||||
\
|
||||
free(node); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_prv(SNAME##_node *node) \
|
||||
{ \
|
||||
if (node->prev == NULL) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *tmp = node->prev; \
|
||||
\
|
||||
if (node->prev != NULL) \
|
||||
{ \
|
||||
node->prev = node->prev->prev; \
|
||||
node->prev->next = node; \
|
||||
} \
|
||||
else \
|
||||
node->owner->head = node; \
|
||||
\
|
||||
free(tmp); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_node *PFX##_new_node(SNAME *_owner_, T element) \
|
||||
{ \
|
||||
SNAME##_node *node = malloc(sizeof(SNAME##_node)); \
|
||||
\
|
||||
if (!node) \
|
||||
return NULL; \
|
||||
\
|
||||
node->owner = _owner_; \
|
||||
node->data = element; \
|
||||
node->next = NULL; \
|
||||
node->prev = NULL; \
|
||||
\
|
||||
return node; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_node *PFX##_get_node(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return NULL; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_node *scan = NULL; \
|
||||
\
|
||||
if (index <= _list_->count / 2) \
|
||||
{ \
|
||||
scan = _list_->head; \
|
||||
for (size_t i = 0; i < index; i++) \
|
||||
{ \
|
||||
scan = scan->next; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
scan = _list_->tail; \
|
||||
for (size_t i = _list_->count - 1; i > index; i--) \
|
||||
{ \
|
||||
scan = scan->prev; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return scan; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->head; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor->prev == NULL && iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor->next == NULL && iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->head; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = false; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->tail; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = false; \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->index; \
|
||||
*result = iter->cursor->data; \
|
||||
iter->start = false; \
|
||||
\
|
||||
if (iter->cursor->next == NULL) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = iter->cursor->next; \
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->index; \
|
||||
*result = iter->cursor->data; \
|
||||
iter->end = false; \
|
||||
\
|
||||
if (iter->cursor->prev == NULL) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = iter->cursor->prev; \
|
||||
iter->index--; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
#define LINKEDLIST_GENERATE_SOURCE(PFX, SNAME, FMOD, K, T) \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(void) \
|
||||
{ \
|
||||
SNAME *_list_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_list_) \
|
||||
return NULL; \
|
||||
\
|
||||
_list_->count = 0; \
|
||||
_list_->head = NULL; \
|
||||
_list_->tail = NULL; \
|
||||
\
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_list_) \
|
||||
{ \
|
||||
SNAME##_node *scan = _list_->head; \
|
||||
while (_list_->head != NULL) \
|
||||
{ \
|
||||
_list_->head = _list_->head->next; \
|
||||
free(scan); \
|
||||
scan = _list_->head; \
|
||||
} \
|
||||
free(_list_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, T element) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_new_node(_list_, element); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
{ \
|
||||
_list_->head = node; \
|
||||
_list_->tail = node; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
node->next = _list_->head; \
|
||||
_list_->head->prev = node; \
|
||||
_list_->head = node; \
|
||||
} \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_list_, T element, size_t index) \
|
||||
{ \
|
||||
if (index > _list_->count) \
|
||||
return false; \
|
||||
\
|
||||
if (index == 0) \
|
||||
{ \
|
||||
return PFX##_push_front(_list_, element); \
|
||||
} \
|
||||
else if (index == _list_->count) \
|
||||
{ \
|
||||
return PFX##_push_back(_list_, element); \
|
||||
} \
|
||||
\
|
||||
SNAME##_node *node = PFX##_new_node(_list_, element); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *scan = PFX##_get_node(_list_, index - 1); \
|
||||
\
|
||||
node->next = scan->next; \
|
||||
node->prev = scan; \
|
||||
node->next->prev = node; \
|
||||
node->prev->next = node; \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, T element) \
|
||||
{ \
|
||||
SNAME##_node *node = PFX##_new_node(_list_, element); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
{ \
|
||||
_list_->head = node; \
|
||||
_list_->tail = node; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
node->prev = _list_->tail; \
|
||||
_list_->tail->next = node; \
|
||||
_list_->tail = node; \
|
||||
} \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *node = _list_->head; \
|
||||
_list_->head = _list_->head->next; \
|
||||
\
|
||||
free(node); \
|
||||
\
|
||||
if (_list_->head == NULL) \
|
||||
_list_->tail = NULL; \
|
||||
else \
|
||||
_list_->head->prev = NULL; \
|
||||
\
|
||||
_list_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
if (index == 0) \
|
||||
{ \
|
||||
return PFX##_pop_front(_list_); \
|
||||
} \
|
||||
else if (index == _list_->count - 1) \
|
||||
{ \
|
||||
return PFX##_pop_back(_list_); \
|
||||
} \
|
||||
\
|
||||
SNAME##_node *node = PFX##_get_node(_list_, index); \
|
||||
\
|
||||
if (!node) \
|
||||
return false; \
|
||||
\
|
||||
node->next->prev = node->prev; \
|
||||
node->prev->next = node->next; \
|
||||
\
|
||||
free(node); \
|
||||
\
|
||||
_list_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *node = _list_->tail; \
|
||||
_list_->tail = _list_->tail->prev; \
|
||||
\
|
||||
free(node); \
|
||||
\
|
||||
if (_list_->tail == NULL) \
|
||||
_list_->head = NULL; \
|
||||
else \
|
||||
_list_->tail->next = NULL; \
|
||||
\
|
||||
_list_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_if(SNAME *_list_, T element, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_list_, element, index); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_list_, index); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->head->data; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_get(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return 0; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
SNAME##_node *scan = PFX##_get_node(_list_, index); \
|
||||
\
|
||||
if (scan == NULL) \
|
||||
return 0; \
|
||||
\
|
||||
return scan->data; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->tail->data; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_nxt(SNAME##_node *node, T element) \
|
||||
{ \
|
||||
SNAME##_node *new_node = PFX##_new_node(node->owner, element); \
|
||||
\
|
||||
if (!new_node) \
|
||||
return false; \
|
||||
\
|
||||
new_node->next = node->next; \
|
||||
if (node->next != NULL) \
|
||||
node->next->prev = new_node; \
|
||||
else \
|
||||
node->owner->tail = new_node; \
|
||||
\
|
||||
new_node->prev = node; \
|
||||
node->next = new_node; \
|
||||
\
|
||||
node->owner->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_prv(SNAME##_node *node, T element) \
|
||||
{ \
|
||||
SNAME##_node *new_node = PFX##_new_node(node->owner, element); \
|
||||
\
|
||||
if (!new_node) \
|
||||
return false; \
|
||||
\
|
||||
new_node->prev = node->prev; \
|
||||
if (node->prev != NULL) \
|
||||
node->prev->next = new_node; \
|
||||
else \
|
||||
node->owner->head = new_node; \
|
||||
\
|
||||
new_node->next = node; \
|
||||
node->prev = new_node; \
|
||||
\
|
||||
node->owner->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_nxt(SNAME##_node *node) \
|
||||
{ \
|
||||
if (node->next == NULL) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *tmp = node->next; \
|
||||
\
|
||||
if (node->next != NULL) \
|
||||
{ \
|
||||
node->next = node->next->next; \
|
||||
node->next->prev = node; \
|
||||
} \
|
||||
else \
|
||||
node->owner->tail = node; \
|
||||
\
|
||||
node->owner->count--; \
|
||||
\
|
||||
free(tmp); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_cur(SNAME##_node *node) \
|
||||
{ \
|
||||
if (node->prev != NULL) \
|
||||
node->prev->next = node->next; \
|
||||
else \
|
||||
node->owner->head = node->next; \
|
||||
\
|
||||
if (node->next != NULL) \
|
||||
node->next->prev = node->prev; \
|
||||
else \
|
||||
node->owner->tail = node->prev; \
|
||||
\
|
||||
node->owner->count--; \
|
||||
\
|
||||
free(node); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_prv(SNAME##_node *node) \
|
||||
{ \
|
||||
if (node->prev == NULL) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *tmp = node->prev; \
|
||||
\
|
||||
if (node->prev != NULL) \
|
||||
{ \
|
||||
node->prev = node->prev->prev; \
|
||||
node->prev->next = node; \
|
||||
} \
|
||||
else \
|
||||
node->owner->head = node; \
|
||||
\
|
||||
free(tmp); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_node *PFX##_new_node(SNAME *_owner_, T element) \
|
||||
{ \
|
||||
SNAME##_node *node = malloc(sizeof(SNAME##_node)); \
|
||||
\
|
||||
if (!node) \
|
||||
return NULL; \
|
||||
\
|
||||
node->owner = _owner_; \
|
||||
node->data = element; \
|
||||
node->next = NULL; \
|
||||
node->prev = NULL; \
|
||||
\
|
||||
return node; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_node *PFX##_get_node(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return NULL; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME##_node *scan = NULL; \
|
||||
\
|
||||
if (index <= _list_->count / 2) \
|
||||
{ \
|
||||
scan = _list_->head; \
|
||||
for (size_t i = 0; i < index; i++) \
|
||||
{ \
|
||||
scan = scan->next; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
scan = _list_->tail; \
|
||||
for (size_t i = _list_->count - 1; i > index; i--) \
|
||||
{ \
|
||||
scan = scan->prev; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return scan; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->head; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor->prev == NULL && iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor->next == NULL && iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->head; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = false; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->tail; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = false; \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->index; \
|
||||
*result = iter->cursor->data; \
|
||||
iter->start = false; \
|
||||
\
|
||||
if (iter->cursor->next == NULL) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = iter->cursor->next; \
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->index; \
|
||||
*result = iter->cursor->data; \
|
||||
iter->end = false; \
|
||||
\
|
||||
if (iter->cursor->prev == NULL) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = iter->cursor->prev; \
|
||||
iter->index--; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_LINKEDLIST_H */
|
||||
+329
-329
@@ -54,336 +54,336 @@
|
||||
}; \
|
||||
\
|
||||
/* HEADER ********************************************************************/
|
||||
#define LIST_GENERATE_HEADER(PFX, SNAME, FMOD, K, T) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size); \
|
||||
FMOD void PFX##_free(SNAME *_list_); \
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, T element); \
|
||||
FMOD bool PFX##_push(SNAME *_list_, T element, size_t index); \
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, T element); \
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index); \
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_); \
|
||||
FMOD bool PFX##_insert_if(SNAME *_list_, T element, size_t index, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_list_, size_t index, bool condition); \
|
||||
FMOD T PFX##_back(SNAME *_list_); \
|
||||
FMOD T PFX##_get(SNAME *_list_, size_t index); \
|
||||
FMOD T PFX##_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_empty(SNAME *_list_); \
|
||||
FMOD bool PFX##_full(SNAME *_list_); \
|
||||
FMOD size_t PFX##_count(SNAME *_list_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_list_); \
|
||||
\
|
||||
FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index); \
|
||||
\
|
||||
#define LIST_GENERATE_HEADER(PFX, SNAME, FMOD, K, T) \
|
||||
\
|
||||
typedef struct SNAME##_s SNAME; \
|
||||
typedef struct SNAME##_iter_s SNAME##_iter; \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size); \
|
||||
FMOD void PFX##_free(SNAME *_list_); \
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, T element); \
|
||||
FMOD bool PFX##_push(SNAME *_list_, T element, size_t index); \
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, T element); \
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index); \
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_); \
|
||||
FMOD bool PFX##_push_if(SNAME *_list_, T element, size_t index, bool condition); \
|
||||
FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition); \
|
||||
FMOD T PFX##_back(SNAME *_list_); \
|
||||
FMOD T PFX##_get(SNAME *_list_, size_t index); \
|
||||
FMOD T PFX##_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_empty(SNAME *_list_); \
|
||||
FMOD bool PFX##_full(SNAME *_list_); \
|
||||
FMOD size_t PFX##_count(SNAME *_list_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_list_); \
|
||||
\
|
||||
FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target); \
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter); \
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter); \
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index); \
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index); \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, K, T) \
|
||||
\
|
||||
FMOD bool PFX##_grow(SNAME *_list_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size) \
|
||||
{ \
|
||||
if (size < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_list_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_list_) \
|
||||
return NULL; \
|
||||
\
|
||||
_list_->buffer = malloc(sizeof(T) * size); \
|
||||
\
|
||||
if (!_list_->buffer) \
|
||||
{ \
|
||||
free(_list_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
for (size_t i = 0; i < size; i++) \
|
||||
{ \
|
||||
_list_->buffer[i] = 0; \
|
||||
} \
|
||||
\
|
||||
_list_->capacity = size; \
|
||||
_list_->count = 0; \
|
||||
\
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_list_) \
|
||||
{ \
|
||||
free(_list_->buffer); \
|
||||
free(_list_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, T element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
if (!PFX##_grow(_list_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (!PFX##_empty(_list_)) \
|
||||
{ \
|
||||
for (size_t i = _list_->count; i > 0; i--) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[i - 1]; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[0] = element; \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_list_, T element, size_t index) \
|
||||
{ \
|
||||
if (index > _list_->count) \
|
||||
return false; \
|
||||
\
|
||||
if (index == 0) \
|
||||
{ \
|
||||
return PFX##_push_front(_list_, element); \
|
||||
} \
|
||||
else if (index == _list_->count) \
|
||||
{ \
|
||||
return PFX##_push_back(_list_, element); \
|
||||
} \
|
||||
\
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
if (!PFX##_grow(_list_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
for (size_t i = _list_->count; i > index; i--) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[i - 1]; \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[index] = element; \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, T element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
if (!PFX##_grow(_list_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[_list_->count++] = element; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[i + 1]; \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[--_list_->count] = 0; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
if (index == 0) \
|
||||
{ \
|
||||
return PFX##_pop_front(_list_); \
|
||||
} \
|
||||
else if (index == _list_->count - 1) \
|
||||
{ \
|
||||
return PFX##_pop_back(_list_); \
|
||||
} \
|
||||
\
|
||||
for (size_t i = index; i < _list_->count - 1; i++) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[i + 1]; \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[--_list_->count] = 0; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
_list_->buffer[--_list_->count] = 0; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_list_, T element, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_list_, element, index); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_if(SNAME *_list_, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_list_, index); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_get(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return 0; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->buffer[index]; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->buffer[_list_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count >= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_grow(SNAME *_list_) \
|
||||
{ \
|
||||
size_t new_capacity = _list_->capacity * 2; \
|
||||
\
|
||||
T *new_buffer = realloc(_list_->buffer, sizeof(T) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
_list_->buffer = new_buffer; \
|
||||
_list_->capacity = new_capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor == 0 && iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor == iter->target->count - 1 && iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = false; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = false; \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->cursor; \
|
||||
*result = iter->target->buffer[iter->cursor]; \
|
||||
iter->start = false; \
|
||||
\
|
||||
if (iter->cursor == iter->target->count - 1) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->cursor; \
|
||||
*result = iter->target->buffer[iter->cursor]; \
|
||||
iter->end = false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
#define LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, K, T) \
|
||||
\
|
||||
FMOD bool PFX##_grow(SNAME *_list_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t size) \
|
||||
{ \
|
||||
if (size < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_list_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_list_) \
|
||||
return NULL; \
|
||||
\
|
||||
_list_->buffer = malloc(sizeof(T) * size); \
|
||||
\
|
||||
if (!_list_->buffer) \
|
||||
{ \
|
||||
free(_list_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
for (size_t i = 0; i < size; i++) \
|
||||
{ \
|
||||
_list_->buffer[i] = 0; \
|
||||
} \
|
||||
\
|
||||
_list_->capacity = size; \
|
||||
_list_->count = 0; \
|
||||
\
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_list_) \
|
||||
{ \
|
||||
free(_list_->buffer); \
|
||||
free(_list_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, T element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
if (!PFX##_grow(_list_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (!PFX##_empty(_list_)) \
|
||||
{ \
|
||||
for (size_t i = _list_->count; i > 0; i--) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[i - 1]; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[0] = element; \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_list_, T element, size_t index) \
|
||||
{ \
|
||||
if (index > _list_->count) \
|
||||
return false; \
|
||||
\
|
||||
if (index == 0) \
|
||||
{ \
|
||||
return PFX##_push_front(_list_, element); \
|
||||
} \
|
||||
else if (index == _list_->count) \
|
||||
{ \
|
||||
return PFX##_push_back(_list_, element); \
|
||||
} \
|
||||
\
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
if (!PFX##_grow(_list_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
for (size_t i = _list_->count; i > index; i--) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[i - 1]; \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[index] = element; \
|
||||
\
|
||||
_list_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, T element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
if (!PFX##_grow(_list_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[_list_->count++] = element; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[i + 1]; \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[--_list_->count] = 0; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
if (index == 0) \
|
||||
{ \
|
||||
return PFX##_pop_front(_list_); \
|
||||
} \
|
||||
else if (index == _list_->count - 1) \
|
||||
{ \
|
||||
return PFX##_pop_back(_list_); \
|
||||
} \
|
||||
\
|
||||
for (size_t i = index; i < _list_->count - 1; i++) \
|
||||
{ \
|
||||
_list_->buffer[i] = _list_->buffer[i + 1]; \
|
||||
} \
|
||||
\
|
||||
_list_->buffer[--_list_->count] = 0; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
\
|
||||
_list_->buffer[--_list_->count] = 0; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_if(SNAME *_list_, T element, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_list_, element, index); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_list_, index); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_get(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return 0; \
|
||||
\
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->buffer[index]; \
|
||||
} \
|
||||
\
|
||||
FMOD T PFX##_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return 0; \
|
||||
\
|
||||
return _list_->buffer[_list_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count >= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_grow(SNAME *_list_) \
|
||||
{ \
|
||||
size_t new_capacity = _list_->capacity * 2; \
|
||||
\
|
||||
T *new_buffer = realloc(_list_->buffer, sizeof(T) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
_list_->buffer = new_buffer; \
|
||||
_list_->capacity = new_capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor == 0 && iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor == iter->target->count - 1 && iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_tostart(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = false; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_toend(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = false; \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter, T *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->cursor; \
|
||||
*result = iter->target->buffer[iter->cursor]; \
|
||||
iter->start = false; \
|
||||
\
|
||||
if (iter->cursor == iter->target->count - 1) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter, T *result, size_t *index) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
*index = iter->cursor; \
|
||||
*result = iter->target->buffer[iter->cursor]; \
|
||||
iter->end = false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* CMC_LIST_H */
|
||||
Reference in new issue
Block a user