/* Example: custom type dynamic array, local instantiation (no separate header), custom vector type */
/* Part of genvector examples (http://repo.hu/projects/genvector) */

/* The generic engine is instantiated locally. The new instance,
   vtf0_* represents a dynamic array of floats, new elements initialized to 0.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* Instantiate the engine as vtf0. Notes:
 - GVT_FUNC is defined to static so that all functions created are static,
   non-likable (this instance is exclusively used in this file). For modern
   C compilers this also means functions might be inlined.
 - <genvector/genvector_undef.h> is included so that all GVT_ defines are
   #undef'd. This allows the code to instantiate two different vectors in
   the same file (the second instantiation needs the same GVT_ macros
   to be defined)

/**************** vector instance vtf0_ ****************/
#define GVT(x) vtf0_ ## x
#define GVT_ELEM_TYPE float
#define GVT_SIZE_TYPE size_t
#define GVT_DOUBLING_THRS 4096
#define GVT_START_SIZE 32
#define GVT_FUNC static
#define GVT_SET_NEW_BYTES_TO 0
#define GVT_REALLOC(vect, ptr, size)  realloc(ptr, size)
#define GVT_FREE(vect, ptr)           free(ptr)
#include <genvector/genvector_impl.h>
#include <genvector/genvector_impl.c>
#include <genvector/genvector_undef.h>
/**************** vector instance vtf0_ ****************/

/* print the array with a prefix */
static void dump(const char *prefix, vtf0_t *v)
{
	if (v->array != NULL) {
		int n;
		printf("%-12s", prefix);
		for(n = 0; n < vtf0_len(v); n++)
			printf(" %.2f", v->array[n]);
		printf("\n");
	}
	else
		printf("%-12s <NULL>\n", prefix);
}

int main()
{
	int n;
	vtf0_t a, a2;
	float farr[] = {2.01, 4, 8, 16};
	float farr2[] = {7, 6, 5.55, 4};

	/* Initialize the vector (to empty, which means the array is not allocated) */
	vtf0_init(&a);
	dump("empty: ", &a);


	/* append 100..109, int by int */
	for(n = 0; n < 10; n++)
		vtf0_append(&a, 100+n);
	dump("append: ", &a);

	/* append a static array */
	vtf0_append_len(&a, farr, sizeof(farr)/sizeof(int));
	dump("append_len: ", &a);

	/* truncate after 8 elements */
	vtf0_truncate(&a, 8);
	dump("truncate: ", &a);

	/* Concat two vectors: sort of "s += s2" */
	vtf0_init(&a2);
	vtf0_append_len(&a, farr2, sizeof(farr2)/sizeof(int));
	vtf0_concat(&a, &a2);
	dump("concat: ", &a);

	/* Array is still just an int * array */
	printf("[3] is:      %.2f\n", a.array[3]);

	/* It can be read or written as an int * array, within bounds */
	a.array[5] = 99;
	dump("array asg: ", &a);

	/* Initializing an element beyond current end will create multiple
	   new elements, all initialized to 0 */
	vtf0_set(&a, 15, 77);
	dump("set: ", &a);

	/* Remove a mid-section of the array, 3 elements starting from [2] */
	vtf0_remove(&a, 2, 3);
	dump("remove: ", &a);

	/* Free memory */
	vtf0_uninit(&a);
	vtf0_uninit(&a2);

	return 0;
}
