Приветствую!
Есть такой код
typedef struct
{
char * name;
} widget;
void widget_destroy(widget * src)
{
unised(src);
}
И такой
typedef struct
{
size_t total;
size_t pos;
widget * data;
} widget_vector;
Этот вектор генерируется прогой.
#ifndef _CONTAINERS_widget_H
#define _CONTAINERS_widget_H
typedef struct
{
size_t total;
size_t pos;
widget * data;
} widget_vector;
inline widget_vector * widget_vector_new(size_t count)
{
widget_vector * p = (widget_vector*)calloc(1, sizeof(widget_vector));
p->total = count;
p->pos = 0;
p->data = (widget*)calloc(p->total, sizeof(widget));
return p;
}
inline void widget_vector_clear(widget_vector * src)
{
src->pos = 0;
}
inline size_t widget_vector_size(widget_vector * src)
{
return src->pos;
}
inline size_t widget_vector_capacity(widget_vector * src)
{
return src->total;
}
inline widget * widget_vector_get(widget_vector * src, size_t idx)
{
assert(idx <= widget_vector_size(src));
return &src->data[idx];
}
inline void widget_vector_free(widget_vector * src)
{
for (size_t i = 0; i < widget_vector_size(src); i++)
{
widget * j = widget_vector_get(src, i);
widget_destroy(j);
}
free(src->data);
free(src);
}
/*
inline void widget_vector_free(widget_vector * src)
{
free(src->data);
free(src);
}
*/
inline void widget_vector_set(widget_vector * src, size_t idx, widget val)
{
memcpy(&src->data[idx], &val, sizeof(widget));
}
inline void widget_vector_resize(widget_vector * src, size_t count)
{
if (count > src->total)
{
src->total = count;
src->data = (widget*)realloc(src->data, src->total * sizeof(widget));
}
}
inline void widget_vector_push_back(widget_vector * src, const widget val)
{
if (src->pos + 1 > src->total)
{
src->total = src->total * 2;
src->data = (widget*)realloc(src->data, src->total * sizeof(widget));
}
memcpy(&src->data[src->pos], &val, sizeof(widget));
src->pos++;
}
typedef struct
{
size_t total;
size_t pos;
widget ** data;
} widget_ptr_vector;
inline widget_ptr_vector * widget_ptr_vector_new(size_t count)
{
widget_ptr_vector * p = (widget_ptr_vector*)calloc(1, sizeof(widget_ptr_vector));
p->total = count;
p->pos = 0;
p->data = (widget**)calloc(p->total, sizeof(widget*));
return p;
}
inline void widget_ptr_vector_clear(widget_ptr_vector * src)
{
src->pos = 0;
}
inline size_t widget_ptr_vector_size(widget_ptr_vector * src)
{
return src->pos;
}
inline size_t widget_ptr_vector_capacity(widget_ptr_vector * src)
{
return src->total;
}
inline widget * widget_ptr_vector_get(widget_ptr_vector * src, size_t idx)
{
assert(idx <= widget_ptr_vector_size(src));
return src->data[idx];
}
inline void widget_ptr_vector_free(widget_ptr_vector * src)
{
for (size_t i = 0; i < widget_ptr_vector_size(src); i++)
{
widget * j = widget_ptr_vector_get(src, i);
widget_destroy(j);
}
free(src->data);
free(src);
}
/*
inline void widget_ptr_vector_free(widget_ptr_vector * src)
{
free(src->data);
free(src);
}
*/
inline void widget_ptr_vector_set(widget_ptr_vector * src, size_t idx, widget * val)
{
src->data[idx] = val;
}
inline void widget_ptr_vector_resize(widget_ptr_vector * src, size_t count)
{
if (count > src->total)
{
src->total = count;
src->data = (widget**)realloc(src->data, src->total * sizeof(widget*));
}
}
inline void widget_ptr_vector_push_back(widget_ptr_vector * src, widget * val)
{
if (src->pos + 1 > src->total)
{
src->total = src->total * 2;
src->data = (widget**)realloc(src->data, src->total * sizeof(widget*));
}
src->data[src->pos] = val;
src->pos++;
}
typedef struct
{
size_t total;
widget * objs;
bool * used;
} widget_object_pool;
inline widget_object_pool * widget_object_pool_new(size_t count)
{
widget_object_pool * p = (widget_object_pool*)calloc(1, sizeof(widget_object_pool));
p->total = count;
p->objs = (widget*)calloc(p->total, sizeof(widget));
p->used = (bool*)calloc(p->total, sizeof(bool));
return p;
}
inline void widget_object_pool_free(widget_object_pool * src)
{
for (size_t i = 0; i < src->total; i++)
{
//widget_destroy(&src->objs[i]);
}
free(src->objs);
free(src->used);
free(src);
}
inline bool widget_object_pool_find_free(widget_object_pool * src, size_t * idx)
{
for (size_t i = 0; i < src->total; i++)
{
if (src->used[i] == false)
{
*idx = i;
return true;
}
}
return false;
}
inline void widget_object_pool_remove(widget_object_pool * src, widget * val)
{
size_t i = 0;
while ((i < src->total) && (&src->objs[i] != val))
{
i++;
}
if (i < src->total)
{
src->used[i] = false;
}
}
inline widget * widget_object_pool_alloc(widget_object_pool * src)
{
size_t i = 0;
assert(widget_object_pool_find_free(src, &i));
src->used[i] = true;
return &src->objs[i];
}
typedef struct widget_hash_node
{
widget data;
char * key;
size_t hash;
struct widget_hash_node * next;
struct widget_hash_node * prev;
} widget_hash_node;
typedef struct widget_hash_list
{
struct widget_hash_node * head;
struct widget_hash_node * tail;
} widget_hash_list;
typedef struct widget_hash
{
size_t total;
widget_hash_list * list;
} widget_hash;
inline size_t widget_hash_size(widget_hash * src)
{
return src->total;
}
inline widget_hash * widget_hash_new(size_t count)
{
widget_hash * p = (widget_hash*)calloc(1, sizeof(widget_hash));
p->total = count;
p->list = (widget_hash_list*)calloc(p->total, sizeof(widget_hash_list));
return p;
}
inline void widget_hash_list_push_back(widget_hash_list * list, widget_hash_node * elem)
{
if (list->head == NULL)
{
list->head = elem;
elem->prev = NULL;
}
else
{
list->tail->next = elem;
elem->prev = list->tail;
}
list->tail = elem;
elem->next = NULL;
}
inline unsigned int widget_hash_hashed(const char * str)
{
unsigned int hash = 0;
for(; *str; str++)
hash = (hash * 1664525) + (unsigned char)(*str) + 1013904223;
return hash;
}
inline widget_hash_node * widget_hash_node_new(const char * key, widget data)
{
widget_hash_node * p = (widget_hash_node*)calloc(1, sizeof(widget_hash_node));
p->hash = widget_hash_hashed(key);
p->key = strdup(key);
memcpy(&p->data, &data, sizeof(widget));
return p;
}
inline widget_hash_node * widget_hash_find_node(widget_hash * src, const char * key)
{
size_t h = widget_hash_hashed(key) % src->total;
for (widget_hash_node * i = src->list[h].head; i != NULL; i = i->next)
{
if (strcmp(i->key, key) == 0)
{
return i;
}
}
return NULL;
}
inline void widget_hash_insert(widget_hash * src, const char * key, widget data)
{
widget_hash_node * i = widget_hash_find_node(src, key);
unised(data);
if (i == NULL)
{
i = widget_hash_node_new(key, data);
widget_hash_list_push_back(&src->list[i->hash % src->total], i);
}
}
inline widget * widget_hash_find(widget_hash * src, const char * key)
{
widget_hash_node * i = widget_hash_find_node(src, key);
if (i != NULL)
{
return &i->data;
}
return NULL;
}
inline void widget_hash_list_destroy(widget_hash_list * list)
{
widget_hash_node * curr;
widget_hash_node * next;
curr = list->head;
while (curr != NULL)
{
next = curr->next;
free(curr);
curr = next;
}
list->head = NULL;
list->tail = NULL;
}
inline void widget_hash_free(widget_hash * src)
{
for (size_t i = 0; i < src->total; i++)
{
if (src->list[i].head != NULL)
{
widget_hash_list_destroy(&src->list[i]);
}
}
}
inline void widget_hash_list_remove(widget_hash_list * list, widget_hash_node * elem)
{
if (elem == list->head)
{
if (elem->next != NULL)
{
list->head = elem->next;
elem->next->prev = NULL;
}
else
{
list->head = NULL;
}
}
else if (elem == list->tail)
{
if (elem->prev != NULL)
{
list->tail = elem->prev;
elem->prev->next = NULL;
}
else
{
list->tail = NULL;
}
}
else
{
elem->next->prev = elem->prev;
elem->prev->next = elem->next;
}
}
inline widget * widget_new()
{
widget * p = (widget*)calloc(1, sizeof(widget));
return p;
}
#endif
Каждый в своих h файлах
Но мне нужно что бы работал вот такой код
typedef struct
{
char * name;
widget_vector * childs;
} widget;
Как объявить widget так что бы код стал валидным?
#include "widget.h"
#include "containers/containers_widget.h"
Если объявить код так,
#include "containers/containers_widget.h"//widget_vector
#include "widget.h"
Естественно компилятор ругается на отсутствие widget
В С++ можно так
class widget; и все ок
В си
struct widget; Не работает.
Это мои эксперименты с кодогенерацией.