2 registered members (Akow, tomaslolo),
1,536
guests, and 12
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
replacement for c++ arrays
#115907
03/07/07 21:26
03/07/07 21:26
|
Joined: Jan 2003
Posts: 4,615 Cambridge
Joey
OP
Expert
|
OP
Expert
Joined: Jan 2003
Posts: 4,615
Cambridge
|
hi there! i just thought with all this asking about arrays i could post a "kind of"-solution. it's a completely working (well, at least it's ansi c, didn't try it with lite-c) linked list with adding and removal &c. &c. see for yourself. Code:
struct llink { struct llink *prev, *next; void *p; }; struct llist { struct llink *start; };
llist* new_llist(void) { llist* list = (llist*)malloc(sizeof(llist)); if (list == NULL) { return (llist*)NULL; } list->start = NULL; return list; }
llink* llist_add(llist *list, void *p) { llink *link; if (list == NULL) { return (llink*)NULL; }
link = (llink*)malloc(sizeof(llink)); if (link == NULL) { return (llink*)NULL; }
link->p = p; if (list->start == NULL) { list->start = link->next = link->prev = link; } else { // reassign left side link->prev = list->start->prev; list->start->prev->next = link;
// reassign right side link->next = list->start; list->start->prev = link; } return link; }
size_t llist_size(llist *list) { size_t i = 1; llink *start, *current; if ( (list == NULL) || (list->start == NULL) ) { return 0; }
current = start = list->start; while ( (current = current->next, current) != start ) { i ++; }
return i; }
llink* llist_get_link(llist *list, size_t offset) { size_t c_offset; llink *current; if ( (list == NULL) || (list->start == NULL) ) { return NULL; }
c_offset = offset%llist_size(list); current = list->start; for (c_offset; c_offset > 0; c_offset --) { current = current->next; }
return current; }
void* llist_get(llist *list, size_t offset) { llink *current = llist_get_link(list, offset); return (current == NULL) ? NULL : current->p; }
bool llist_delete(llist *list, size_t offset) { llink *victim; if ( (victim = llist_get_link(list, offset)) == NULL ) { return false; }
if (llist_size(list) == 1) { free(victim); list->start = NULL; return true; }
if (offset == 0) { list->start = victim->next; }
// reclose list victim->prev->next = victim->next; victim->next->prev = victim->prev; free(victim); return true; }
signed long int llist_index_of(llist *list, void *p) { size_t i = llist_size(list); llink *current; if (i == 0) { // implies list->start == NULL return -1; }
current = list->start; for (i; i > 0; i --) { if (current->p == p) { return (signed long int)i; } current = current->next; }
return -1; }
if you want any function added, just tell me. greetings, joey.
|
|
|
Re: replacement for c++ arrays
[Re: Joey]
#115908
03/07/07 21:53
03/07/07 21:53
|
Joined: Jan 2003
Posts: 4,615 Cambridge
Joey
OP
Expert
|
OP
Expert
Joined: Jan 2003
Posts: 4,615
Cambridge
|
woohops, just noticed that there's a lite-c contributions thread-containing-thingy... well, could someone move the thread? anyway, here's a usage example: Code:
llist *list = new_llist(); char foo[] = "test", fuzz[] = "schnarch"; int *arr = (int*)malloc(20000*sizeof(int));
llist_add(list, &foo); llist_add(list, &fuzz); llist_add(list, &arr);
size_t size = llist_size(list); // returns 3 char *test = (char*)llist_get(list, 0); // returns "test"
signed long int v = llist_index_of(list, &fuzz); // returns 1
llist_delete(list, 0); // returns true size = llist_size(list); // returns 2
int *test2 = (int*)llist_get(list, llist_index_of(list, &arr)); // returns the allocated memory
free(list);
Last edited by Joey; 03/07/07 22:00.
|
|
|
Re: replacement for c++ arrays
[Re: Joozey]
#202423
04/14/08 21:29
04/14/08 21:29
|
Joined: Jan 2003
Posts: 4,615 Cambridge
Joey
OP
Expert
|
OP
Expert
Joined: Jan 2003
Posts: 4,615
Cambridge
|
i'm using two lists of the above example, one for storing the key and the other for the value. the map type is defined as follows: typedef struct {
LIST *keys, *values;
} MAP; implementation of the functins new/add/remove/delete is like above. MAP* new_map(void)
{
MAP* map = (MAP*)malloc(sizeof(MAP));
if (map == NULL) {
return (MAP*)NULL;
}
// two lists containing keys and values
map->keys = new_list();
map->values = new_list();
if (!map->keys || !map->values) {
return (MAP*)NULL;
}
return map;
}
bool delete_map(MAP *map, bool garbage_keys, bool garbage_values)
{
if (map == NULL) {
return false;
}
// autodelete all items
if (!delete_list(map->keys, garbage_keys) || !delete_list(map->values, garbage_values)) {
return false;
}
free(map);
return true;
}
var map_size(MAP* map)
{
if (map == NULL) {
return -1;
}
return list_size(map->keys);
}
bool map_add(MAP* map, void* key, void* value)
{
if (map == NULL) {
return false;
}
if (!list_add(map->keys, key) || !list_add(map->values, value)) {
return false;
}
return true;
}
void* map_get(MAP* map, void* key)
{
if (map == NULL) {
return NULL;
}
return list_get(map->values, list_index_of(map->keys, key));
}
bool map_delete(MAP* map, void* key)
{
if (map == NULL) {
return false;
}
var offset = list_index_of(map->keys, key);
if (offset == -1) {
return false;
}
if (!list_delete(map->keys, offset) || !list_delete(map->values, offset)) {
return false;
}
return true;
} note that it doesn't work for hardcoded values since it also works with pointers for the keys. the advantage is that you can simply add a hashmap to an entity, a panel or whatever else you can imagine. joey.
Last edited by Joey; 04/14/08 21:34. Reason: added hint
|
|
|
Re: replacement for c++ arrays
[Re: Joey]
#202424
04/14/08 21:36
04/14/08 21:36
|
Joined: Oct 2004
Posts: 4,134 Netherlands
Joozey
Expert
|
Expert
Joined: Oct 2004
Posts: 4,134
Netherlands
|
Ah I see, somewhat like a two-dimensional array, but then with a linked list. Well, for datatype recognition you would still require a list of all known types and userdefined structs can not be recognised anyway, of course. So nevermind that idea. Thanx nonetheless !
Click and join the 3dgs irc community! Room: #3dgs
|
|
|
|