Eina inline array usage

This example creates an inline array of chars, adds some elements, prints them, re-purposes the array to store ints, adds some elements and prints that.

We are going to start with a function to compare ints. We need this because the '>' operator is not a function and can't be used where Eina_Compare_Cb is needed.

int
cmp(const void *a, const void *b)
{
return *(int*)a > *(int*)b;
}

And then move on to the code we actually care about, starting with variable declarations and eina initialization:

int main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
Eina_Inarray *iarr;
char ch, *ch2;
int a, *b;
eina_init();
Eina_Inarray
struct _Eina_Inarray Eina_Inarray
Type for the inlined array.
Definition eina_inarray.h:212
eina_init
EINA_API int eina_init(void)
Initializes the Eina library.
Definition eina_main.c:291
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition eina_types.h:339

Creating an inline array is very simple, we just need to know what type we want to store:

iarr = eina_inarray_new(sizeof(char), 0);
eina_inarray_new
EINA_API Eina_Inarray * eina_inarray_new(unsigned int member_size, unsigned int step)
Creates a new inline array.
Definition eina_inarray.c:342

Note
  The second parameter(the step) is left at zero which means that eina chooses an appropriate value, this should only be changed if it's known, beforehand, that how many elements the array has.

Once we have an array we can start adding elements to it. Because the insertion function expects a memory address we have to put the value we want to store in a variable (this should be no problem since in the real world usage that's usually where the value is anyways):

ch = 'a';
eina_inarray_push(iarr, &ch);
eina_inarray_push
EINA_API int eina_inarray_push(Eina_Inarray *array, const void *data)
Copies the data as the last member of the array.
Definition eina_inarray.c:411

Note
  Because the inline array copies the value given to it we can later change `ch`, which we do, without affecting the contents of the array.

So let's add some more elements:

ch = 'b';
eina_inarray_push(iarr, &ch);
ch = 'c';
eina_inarray_push(iarr, &ch);
ch = 'd';
eina_inarray_push(iarr, &ch);

We then iterate over our array and print every position of it. The thing to note here is not so much the values, which are the expected 'a', 'b', 'c', and 'd', but rather the memory address of these values, they are sequential:

printf("Inline array of chars:\n");
EINA_INARRAY_FOREACH(iarr, ch2)
printf("char: %c(pointer: %p)\n", *ch2, ch2);
EINA_INARRAY_FOREACH
#define EINA_INARRAY_FOREACH(array, itr)
Walks through an array linearly from head to tail.
Definition eina_inarray.h:724

We are now going to use our array to store ints, so we need to first erase every member currently on the array:

eina_inarray_flush(iarr);
eina_inarray_flush
EINA_API void eina_inarray_flush(Eina_Inarray *array)
Removes every member from the array.
Definition eina_inarray.c:388

And then to be able to store a different type on the same array, we use the eina_inarray_step_set() function, which is just like the eina_inarray_new() function except it receives an already allocated memory. This time we're going to ask eina to use a step of size 4 because that's how many elements we are going to put in the array:

eina_inarray_step_set(iarr, sizeof(Eina_Inarray), sizeof(int), 4);
eina_inarray_step_set
EINA_API void eina_inarray_step_set(Eina_Inarray *array, unsigned int sizeof_eina_inarray, unsigned int member_size, unsigned int step)
Initializes an inline array.
Definition eina_inarray.c:366

Note
  Strictly speaking the reason to call eina_inarray_step_set() is not because we're storing a different type, but because our types have different sizes. Eina inline arrays don't actually know anything about types, they only deal with blocks of memory of a given size.
  Since eina_inarray_step_set() receives already allocated memory, you can (and it is in fact a good practice) use inline arrays that are not declared as pointers:
  Eina_Inarray arr;
  eina_inarray_step_set(&arr, sizeof(arr), sizeof(int), 4);

And now to add our integer values to the array:

a = 97;
eina_inarray_push(iarr, &a);
a = 98;
eina_inarray_push(iarr, &a);
a = 100;
eina_inarray_push(iarr, &a);

Just to change things up a bit we've left out the 99 value, but we still add it in such a way that it keeps the array ordered. There are many ways to do this, we could use eina_inarray_insert_at(), or we could change the value of the last member using eina_inarray_replace_at() and then append the values in the right order, but for no particular reason we're going to use eina_inarray_insert_sorted() instead:

a = 99;
eina_inarray_insert_sorted(iarr, &a, cmp);
eina_inarray_insert_sorted
EINA_API int eina_inarray_insert_sorted(Eina_Inarray *array, const void *data, Eina_Compare_Cb compare)
Copies the data to the array at a position found by the comparison function.
Definition eina_inarray.c:475

We then print the size of our array, and the array itself, much like last time the values are not surprising, and neither should it be that the memory addresses are contiguous:

printf("Inline array of integers with %d elements:\n", eina_inarray_count(iarr));
eina_inarray_count
EINA_API unsigned int eina_inarray_count(const Eina_Inarray *array)
Counts the number of members in an array.
Definition eina_inarray.c:732
EINA_INARRAY_FOREACH(iarr, b)
printf("int: %d(pointer: %p)\n", *b, b);

Once done we free our array and shutdown eina:

eina_inarray_free(iarr);
eina_shutdown();
}
eina_inarray_free
EINA_API void eina_inarray_free(Eina_Inarray *array)
Frees an array and its members.
Definition eina_inarray.c:355
eina_shutdown
EINA_API int eina_shutdown(void)
Shuts down the Eina library.
Definition eina_main.c:379

The source for this example: eina_inarray_01.c