He notado que en varios lugares de nuestra base de código utilizamos matrices que se expanden dinámicamente, es decir, una matriz base unida a un contador de elementos y un valor de "elementos máximos".¿Un buen C equivalente al vector STL?
Lo que quiero hacer es reemplazarlos con una estructura de datos común y funciones de utilidad, por los motivos habituales orientados a objetos. Los elementos de la matriz pueden ser tipos de datos básicos o estructuras, necesito un acceso aleatorio rápido a los elementos y, preferiblemente, una implementación segura para tipos.
Así que, básicamente, lo que me gustaría utilizar es un vector de STL, pero el código base está restringido a C89, así que tengo que llegar a algo más :-)
lo di un poco de pensamiento y de batida este proyecto inicial, sólo para mostrar lo que estoy destinado a:
/* Type-safe dynamic list in C89 */
#define list_declare(type) typedef struct _##type##_list_t { type * base_array; size_t elements; size_t max_size; } type##_list_t
#define list(type) type##_list_t
#define list_new(type, initial_size) { calloc(initial_size, sizeof(type)), 0, initial_size }
#define list_free(list) free(list.base_array)
#define list_set(list, place, element) if (list.elements < list.max_size) { list.base_array[place] = element; } else { /* Array index out of bounds */ }
#define list_add(list, element) if (list.elements < list.max_size) { list.base_array[list.elements++] = element; } else { /* Expand array then add */ }
#define list_get(list, n) list.base_array[n]
/* Sample usage: */
list_declare(int);
int main(void)
{
list(int) integers = list_new(int, 10);
printf("list[0] = %d\n", list_get(integers, 0));
list_add(integers, 4);
printf("list[0] = %d\n", list_get(integers, 0));
list_set(integers, 0, 3);
printf("list[0] = %d\n", list_get(integers, 0));
list_free(integers);
return EXIT_SUCCESS;
}
... sin embargo, tiene que haber alguien que ha hecho esto antes. Soy consciente de la implementación de FreeBSD sys/queue.h de un concepto similar para algunas colas diferentes, pero no puedo encontrar nada parecido para las matrices.
¿Hay alguien aquí más sabio?
Como mínimo, o bien deshacerse de las macros y reemplazarlos con funciones o corregirlos para que funcionen como funciones. El último implica envolver cualquier macro que sea más que una sola expresión/declaración con 'do {...} while (0)'. –
¿Por qué querría deshacerme de las macros? Reemplazarlos con funciones vencería la independencia del tipo, ya no sería una solución genérica. Además, ¿por qué me gustaría envolver con do ... while? Eso haría imposible devolver valores de las macros similares a funciones. – Christoffer
@christoffer: vuelve a leer el comentario de R. Tenga en cuenta el uso de "o": esas macros de funciones son horribles, debe mejorarlas "reparándolas", como dice R. Esto hace que usar una función macro sea menos sorprendente. Yo personalmente preferiría si las macros de funciones fueron en mayúsculas, por si acaso. – Arafangion