EFL 1.7 svn doobies
[profile/ivi/eina.git] / src / include / eina_inarray.h
1 /* EINA - EFL data type library
2  * Copyright (C) 2012 ProFUSION embedded systems
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifndef EINA_INARRAY_H_
20 #define EINA_INARRAY_H_
21
22 #include "eina_types.h"
23 #include "eina_iterator.h"
24 #include "eina_accessor.h"
25
26 /**
27  * @page eina_inarray_example_01 Eina inline array usage
28  * @dontinclude eina_inarray_01.c
29  *
30  * This example will create an inline array of chars, add some elements, print
31  * it, re-purpose the array to store ints, add some elements and print that.
32  *
33  * We'll start with a function to compare ints we need this because the '>'
34  * operator is not a function and can't be used where Eina_Compare_Cb is needed.
35  * @skip int
36  * @until }
37  *
38  * And then move on to the code we actually care about, starting with variable
39  * declarations and eina initialization:
40  * @until eina_init
41  *
42  * Creating an inline array is very simple, we just need to know what type we
43  * want to store:
44  * @until inarray_new
45  * @note The second parameter(the step) is left at zero which means that eina
46  * will choose an appropriate value, this should @b only be changed if it's
47  * known, beforehand, how many elements the array will have.
48  *
49  * Once we have an array we can start adding elements to it. Because the
50  * insertion function expect a memory address we have to put the value we want
51  * to store in a variable(this should be no problem since in real world usage
52  * that's usually where the value will be anyways):
53  * @until push
54  * @note Because the inline array copies the value given to it we can later
55  * change @c ch, which we do, without affecting the contents of the array.
56  *
57  * So let's add some more elements:
58  * @until push
59  * @until push
60  * @until push
61  *
62  * We will then iterate over our array and print every position of it. The thing
63  * to note here is not so much the values which will be the expected 'a', 'b',
64  * 'c' and 'd', but rather the memory address of these values, they are
65  * sequential:
66  * @until printf
67  * @until printf
68  *
69  * We'll now use our array to store ints, so we need to first erase every member
70  * currently on the array:
71  * @until _flush
72  *
73  * And then to be able to store a different type on the same array we use the
74  * eina_inarray_step_set() function, which is just like the eina_inarray_new()
75  * function except it receives already allocated memory. This time we're going
76  * to ask eina to use a step of size 4 because that's how many elements we'll be
77  * putting on the array:
78  * @until _step_set
79  * @note Strictly speaking the reason to call eina_inarray_step_set() is not
80  * because we're storing different type, but rather because our types have
81  * different sizes. Eina inline arrays don't actually know anything about types,
82  * they only deal in blocks of memory of a given size.
83  * @note Since eina_inarray_step_set() receives already allocated memory you can(and
84  * it is in fact good practice) use inline arrays not declared as pointers:
85  * @code
86  * Eina_Inarray arr;
87  * eina_inarray_step_set(&arr, sizeof(arr), sizeof(int), 4);
88  * @endcode
89  *
90  * And now to add our integer values to the array:
91  * @until push
92  * @until push
93  * @until push
94  *
95  * Just to change things up a bit we've left out the 99 value, but will still
96  * add it in such a way to keep the array ordered. There are many ways to do
97  * this, we could use eina_inarray_insert_at(), or we could change the value
98  * of the last member using eina_inarray_replace_at() and then append the values
99  * in the right order, but for no particular reason we're going to use
100  * eina_inarray_insert_sorted() instead:
101  * @until insert_sorted
102  *
103  * We then print the size of our array, and the array itself, much like last
104  * time the values are not surprising, and neither should it be that the memory
105  * addresses are contiguous:
106  * @until printf
107  * @until printf
108  *
109  * Once done we free our array and shutdown eina:
110  * @until }
111  *
112  * The source for this example: @ref eina_inarray_01_c
113  */
114
115 /**
116  * @page eina_inarray_01_c eina_inarray_01.c
117  * @include eina_inarray_01.c
118  * @example eina_inarray_01.c
119  */
120
121 /**
122  * @page eina_inarray_example_02 Eina inline array of strings
123  * @dontinclude eina_inarray_02.c
124  *
125  * This example will create an inline array of strings, add some elements and
126  * then print them. This example is based on @ref eina_array_01_example_page and
127  * @ref eina_inarray_example_01.
128  *
129  * We start with some variable declarations and eina initialization:
130  * @skip int
131  * @until eina_init
132  *
133  * We then create the array much like we did on @ref eina_inarray_example_01 :
134  * @until inarray_new
135  *
136  * The point were this example significantly differs from the first eina inline
137  * array example. We'll not be adding the strings themselves to the array since
138  * their size varies, we'll store pointer to the strings instead. We therefore
139  * use @c char** to populate our inline array:
140  * @until }
141  *
142  * The source for this example: @ref eina_inarray_02_c
143  */
144
145 /**
146  * @page eina_inarray_02_c eina_inarray_02.c
147  * @include eina_inarray_02.c
148  * @example eina_inarray_02.c
149  */
150
151 /**
152  * @addtogroup Eina_Data_Types_Group Data Types
153  *
154  * @since 1.2
155  *
156  * @{
157  */
158
159 /**
160  * @addtogroup Eina_Containers_Group Containers
161  *
162  * @{
163  */
164
165 /**
166  * @defgroup Eina_Inline_Array_Group Inline Array
167  *
168  * Inline array is a container that stores the data itself not pointers to data,
169  * this means there is no memory fragmentation, also for small data types(such
170  * as char, short, int, etc.) it's more memory efficient.
171  *
172  * Usage of the inline array is very similar to that of other
173  * @ref Eina_Containers_Group, like all arrays adding elements to the beginning
174  * of the array is a lot more costly than appending, so those operations should
175  * be minimized.
176  *
177  * Examples:
178  * @li @ref eina_inarray_example_01
179  * @li @ref eina_inarray_example_02
180  *
181  * @{
182  */
183
184
185 /**
186  * @typedef Eina_Inarray
187  * Inlined array type.
188  *
189  * @since 1.2
190  */
191 typedef struct _Eina_Inarray Eina_Inarray;
192
193 /**
194  * Inline array structure, use #Eina_Inarray typedef instead.
195  *
196  * Do not modify these fields directly, use eina_inarray_step_set() or
197  * eina_inarray_new() instead.
198  *
199  * @since 1.2
200  */
201 struct _Eina_Inarray
202 {
203 #define EINA_ARRAY_VERSION 1
204    int          version; /**< Should match EINA_ARRAY_VERSION used when compiled your apps, provided for ABI compatibility */
205
206    unsigned int member_size; /**< byte size of each entry in members */
207    unsigned int len; /**< number of elements used in members */
208    unsigned int max; /**< number of elements allocated in members */
209    unsigned int step; /**< amount to grow number of members allocated */
210    void *members; /**< actual array of elements */
211    EINA_MAGIC
212 };
213
214 /**
215  * @brief Create new inline array.
216  *
217  * @param member_size size of each member in the array.
218  * @param step when resizing the array, do this using the following
219  *        extra amount.
220  * @return The new inline array table or @c NULL on failure.
221  *
222  * Create a new array where members are inlined in a sequence. Each
223  * member has @a member_size bytes.
224  *
225  * If the @a step is 0, then a safe default is chosen.
226  *
227  * On failure, @c NULL is returned and #EINA_ERROR_OUT_OF_MEMORY is
228  * set. If @a member_size is zero, then @c NULL is returned.
229  *
230  * @see eina_inarray_free()
231  *
232  * @since 1.2
233  */
234 EAPI Eina_Inarray *eina_inarray_new(unsigned int member_size,
235                                     unsigned int step) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
236
237 /**
238  * @brief Free array and its members.
239  * @param array array object
240  *
241  * @see eina_inarray_flush()
242  *
243  * @since 1.2
244  */
245 EAPI void eina_inarray_free(Eina_Inarray *array) EINA_ARG_NONNULL(1);
246
247 /**
248  * @brief Initialize inline array.
249  * @param array array object to initialize.
250  * @param member_size size of each member in the array.
251  * @param step when resizing the array, do this using the following
252  *        extra amount.
253  *
254  * Initialize array. If the @a step is @c 0, then a safe default is
255  * chosen.
256  *
257  * This is useful for arrays inlined into other structures or
258  * allocated at stack.
259  *
260  * @see eina_inarray_flush()
261  *
262  * @since 1.2
263  */
264 EAPI void eina_inarray_step_set(Eina_Inarray *array,
265                                 unsigned int sizeof_eina_inarray,
266                                 unsigned int member_size,
267                                 unsigned int step) EINA_ARG_NONNULL(1);
268
269 /**
270  * @brief Remove every member from array.
271  * @param array array object
272  *
273  * @since 1.2
274  */
275 EAPI void eina_inarray_flush(Eina_Inarray *array) EINA_ARG_NONNULL(1);
276
277 /**
278  * @brief Copy the data as the last member of the array.
279  * @param array array object
280  * @param data data to be copied at the end
281  * @return the index of the new member or -1 on errors.
282  *
283  * Copies the given pointer contents at the end of the array. The
284  * pointer is not referenced, instead it's contents is copied to the
285  * members array using the previously defined @c member_size.
286  *
287  * @see eina_inarray_insert_at().
288  *
289  * @since 1.2
290  */
291 EAPI int eina_inarray_push(Eina_Inarray *array,
292                            const void *data) EINA_ARG_NONNULL(1, 2);
293
294 /**
295  * @brief Copy the data to array at position found by comparison function
296  * @param array array object
297  * @param data data to be copied
298  * @param compare compare function
299  * @return the index of the new member or @c -1 on errors.
300  *
301  * Copies the given pointer contents at the array position defined by
302  * given @a compare function. The pointer is not referenced, instead
303  * it's contents is copied to the members array using the previously
304  * defined @c member_size.
305  *
306  * The data given to @a compare function are the pointer to member
307  * memory itself, do no change it.
308  *
309  * @see eina_inarray_insert_sorted()
310  * @see eina_inarray_insert_at()
311  * @see eina_inarray_push()
312  *
313  * @since 1.2
314  */
315 EAPI int eina_inarray_insert(Eina_Inarray *array,
316                              const void *data,
317                              Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2, 3);
318
319 /**
320  * @brief Copy the data to array at position found by comparison function
321  * @param array array object
322  * @param data data to be copied
323  * @param compare compare function
324  * @return the index of the new member or @c -1 on errors.
325  *
326  * Copies the given pointer contents at the array position defined by
327  * given @a compare function. The pointer is not referenced, instead
328  * it's contents is copied to the members array using the previously
329  * defined @c member_size.
330  *
331  * The data given to @a compare function are the pointer to member
332  * memory itself, do no change it.
333  *
334  * This variation will optimize insertion position assuming the array
335  * is already sorted by doing binary search.
336  *
337  * @see eina_inarray_sort()
338  *
339  * @since 1.2
340  */
341 EAPI int eina_inarray_insert_sorted(Eina_Inarray *array,
342                                     const void *data,
343                                     Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2, 3);
344
345 /**
346  * @brief Find data and remove matching member
347  * @param array array object
348  * @param data data to be found and removed
349  * @return the index of the removed member or @c -1 on errors.
350  *
351  * Find data in the array and remove it. Data may be an existing
352  * member of array (then optimized) or the contents will be matched
353  * using memcmp().
354  *
355  * @see eina_inarray_pop()
356  * @see eina_inarray_remove_at()
357  *
358  * @since 1.2
359  */
360 EAPI int eina_inarray_remove(Eina_Inarray *array,
361                              const void *data) EINA_ARG_NONNULL(1, 2);
362
363 /**
364  * @brief Removes the last member of the array
365  * @param array array object
366  * @return the data poped out of the array.
367  *
368  * Note: The data could be considered valid only until any other operation touch the Inarray.
369  *
370  * @since 1.2
371  */
372 EAPI void *eina_inarray_pop(Eina_Inarray *array) EINA_ARG_NONNULL(1);
373
374 /**
375  * @brief Get the member at given position
376  * @param array array object
377  * @param position member position
378  * @return pointer to current member memory.
379  *
380  * Gets the member given its position in the array. It is a pointer to
381  * its current memory, then it can be invalidated with functions that
382  * changes the array such as eina_inarray_push(),
383  * eina_inarray_insert_at() or eina_inarray_remove_at() or variants.
384  *
385  * See also eina_inarray_lookup() and eina_inarray_lookup_sorted().
386  *
387  * @since 1.2
388  */
389 EAPI void *eina_inarray_nth(const Eina_Inarray *array,
390                             unsigned int position) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
391
392 /**
393  * @brief Copy the data at given position in the array
394  * @param array array object
395  * @param position where to insert the member
396  * @param data data to be copied at position
397  * @return #EINA_TRUE on success, #EINA_FALSE on failure.
398  *
399  * Copies the given pointer contents at the given @a position in the
400  * array. The pointer is not referenced, instead it's contents is
401  * copied to the members array using the previously defined
402  * @c member_size.
403  *
404  * All the members from @a position to the end of the array are
405  * shifted to the end.
406  *
407  * If @a position is equal to the end of the array (equals to
408  * eina_inarray_count()), then the member is appended.
409  *
410  * If @a position is bigger than the array length, it will fail.
411  *
412  * @since 1.2
413  */
414 EAPI Eina_Bool eina_inarray_insert_at(Eina_Inarray *array,
415                                       unsigned int position,
416                                       const void *data) EINA_ARG_NONNULL(1, 3);
417
418 /**
419  * @brief Opens a space at given position, returning its pointer.
420  * @param array array object
421  * @param position where to insert first member (open/allocate space)
422  * @param member_count how many times member_size bytes will be allocated.
423  * @return pointer to first member memory allocated or @c NULL on errors.
424  *
425  * This is similar to eina_inarray_insert_at(), but useful if the
426  * members contents are still unknown or unallocated. It will make
427  * room for the required number of items and return the pointer to the
428  * first item, similar to malloc(member_count * member_size), with the
429  * guarantee all memory is within members array.
430  *
431  * The new member memory is undefined, it's not automatically zeroed.
432  *
433  * All the members from @a position to the end of the array are
434  * shifted to the end.
435  *
436  * If @a position is equal to the end of the array (equals to
437  * eina_inarray_count()), then the member is appended.
438  *
439  * If @a position is bigger than the array length, it will fail.
440  *
441  * @since 1.2
442  */
443 EAPI void *eina_inarray_alloc_at(Eina_Inarray *array,
444                                  unsigned int position,
445                                  unsigned int member_count) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
446
447 /**
448  * @brief Copy the data over the given position.
449  * @param array array object
450  * @param position where to replace the member
451  * @param data data to be copied at position
452  * @return #EINA_TRUE on success, #EINA_FALSE on failure.
453  *
454  * Copies the given pointer contents at the given @a position in the
455  * array. The pointer is not referenced, instead it's contents is
456  * copied to the members array using the previously defined
457  * @c member_size.
458  *
459  * If @a position does not exist, it will fail.
460  *
461  * @since 1.2
462  */
463 EAPI Eina_Bool eina_inarray_replace_at(Eina_Inarray *array,
464                                        unsigned int position,
465                                        const void *data) EINA_ARG_NONNULL(1, 3);
466
467 /**
468  * @brief Remove member at given position
469  * @param array array object
470  * @param position position to be removed
471  * @return #EINA_TRUE on success, #EINA_FALSE on failure.
472  *
473  * The member is removed from array and any members after it are moved
474  * towards the array head.
475  *
476  * See also eina_inarray_pop() and eina_inarray_remove().
477  *
478  * @since 1.2
479  */
480 EAPI Eina_Bool eina_inarray_remove_at(Eina_Inarray *array,
481                                       unsigned int position) EINA_ARG_NONNULL(1);
482
483 /**
484  * @brief Reverse members in the array.
485  * @param array array object
486  *
487  * If you do not want to change the array, just walk its elements
488  * backwards, then use EINA_INARRAY_REVERSE_FOREACH() macro.
489  *
490  * @see EINA_INARRAY_REVERSE_FOREACH()
491  *
492  * @since 1.2
493  */
494 EAPI void eina_inarray_reverse(Eina_Inarray *array) EINA_ARG_NONNULL(1);
495
496 /**
497  * @brief Applies quick sort to array
498  * @param array array object
499  * @param compare compare function
500  *
501  * Applies quick sort to the @a array.
502  *
503  * The data given to @a compare function are the pointer to member
504  * memory itself, do no change it.
505  *
506  * @see eina_inarray_insert_sorted()
507  *
508  * @since 1.2
509  */
510 EAPI void eina_inarray_sort(Eina_Inarray *array,
511                             Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2);
512
513 /**
514  * @brief Search member (linear walk)
515  * @param array array object
516  * @param data member to search using @a compare function.
517  * @param compare compare function
518  * @return the member index or -1 if not found.
519  *
520  * Walks array linearly looking for given data as compared by
521  * @a compare function.
522  *
523  * The data given to @a compare function are the pointer to member
524  * memory itself, do no change it.
525  *
526  * See also eina_inarray_lookup_sorted().
527  *
528  * @since 1.2
529  */
530 EAPI int eina_inarray_search(const Eina_Inarray *array,
531                              const void *data,
532                              Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2, 3);
533
534 /**
535  * @brief Search member (binary search walk)
536  * @param array array object
537  * @param data member to search using @a compare function.
538  * @param compare compare function
539  * @return the member index or @c -1 if not found.
540  *
541  * Uses binary search for given data as compared by @a compare function.
542  *
543  * The data given to @a compare function are the pointer to member
544  * memory itself, do no change it.
545  *
546  * @since 1.2
547  */
548 EAPI int eina_inarray_search_sorted(const Eina_Inarray *array,
549                                     const void *data,
550                                     Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2, 3);
551
552 /**
553  * @brief Call function for each array member
554  * @param array array object
555  * @param function callback function
556  * @param user_data user data given to callback @a function
557  * @return #EINA_TRUE if it successfully iterate all items of the array.
558  *
559  * Call @a function for every given data in @a array.
560  *
561  * Safe way to iterate over an array. @p function should return #EINA_TRUE
562  * as long as you want the function to continue iterating, by
563  * returning #EINA_FALSE it will stop and return #EINA_FALSE as a result.
564  *
565  * The data given to @a function are the pointer to member memory
566  * itself.
567  *
568  * @see EINA_INARRAY_FOREACH()
569  *
570  * @since 1.2
571  */
572 EAPI Eina_Bool eina_inarray_foreach(const Eina_Inarray *array,
573                                     Eina_Each_Cb function,
574                                     const void *user_data) EINA_ARG_NONNULL(1, 2);
575
576 /**
577  * @brief Remove all members that matched.
578  * @param array array object
579  * @param match match function
580  * @param user_data user data given to callback @a match.
581  * @return number of removed entries or -1 on error.
582  *
583  * Remove all entries in the @a array where @a match function
584  * returns #EINA_TRUE.
585  *
586  * @since 1.2
587  */
588 EAPI int eina_inarray_foreach_remove(Eina_Inarray *array,
589                                      Eina_Each_Cb match,
590                                      const void *user_data) EINA_ARG_NONNULL(1, 2);
591
592 /**
593  * @brief number of members in array.
594  * @param array array object
595  * @return number of members in array.
596  *
597  * @since 1.2
598  */
599 EAPI unsigned int eina_inarray_count(const Eina_Inarray *array) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
600
601 /**
602  * @brief Returned a new iterator associated to an array.
603  * @param array array object
604  * @return A new iterator.
605  *
606  * This function returns a newly allocated iterator associated to
607  * @p array.
608  *
609  * If the memory can not be allocated, @c NULL is returned
610  * and #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is
611  * returned.
612  *
613  * @warning if the array structure changes then the iterator becomes
614  *          invalid! That is, if you add or remove members this
615  *          iterator behavior is undefined and your program may crash!
616  *
617  * @since 1.2
618  */
619 EAPI Eina_Iterator *eina_inarray_iterator_new(const Eina_Inarray *array) EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
620
621 /**
622  * @brief Returned a new reversed iterator associated to an array.
623  * @param array array object
624  * @return A new iterator.
625  *
626  * This function returns a newly allocated iterator associated to
627  * @p array.
628  *
629  * Unlike eina_inarray_iterator_new(), this will walk the array backwards.
630  *
631  * If the memory can not be allocated, @c NULL is returned
632  * and #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is
633  * returned.
634  *
635  * @warning if the array structure changes then the iterator becomes
636  *          invalid! That is, if you add or remove nodes this iterator
637  *          behavior is undefined and your program may crash!
638  *
639  * @since 1.2
640  */
641 EAPI Eina_Iterator *eina_inarray_iterator_reversed_new(const Eina_Inarray *array) EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
642
643 /**
644  * @brief Returned a new accessor associated to an array.
645  * @param array array object
646  * @return A new accessor.
647  *
648  * This function returns a newly allocated accessor associated to
649  * @p array.
650  *
651  * If the memory can not be allocated, @c NULL is returned
652  * and #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid accessor is
653  * returned.
654  *
655  * @since 1.2
656  */
657 EAPI Eina_Accessor *eina_inarray_accessor_new(const Eina_Inarray *array) EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
658
659 /**
660  * @def EINA_INARRAY_FOREACH
661  * @brief walks array linearly from head to tail
662  * @param array array object
663  * @param itr the iterator pointer
664  *
665  * @a itr must be a pointer with sizeof(itr*) == array->member_size.
666  *
667  * @warning This is fast as it does direct pointer access, but it will
668  *          not check for @c NULL pointers or invalid array object!
669  *          See eina_inarray_foreach() to do that.
670  *
671  * @warning Do not modify array as you walk it! If that is desired,
672  *          then use eina_inarray_foreach_remove()
673  *
674  * @since 1.2
675  */
676 #define EINA_INARRAY_FOREACH(array, itr)                                \
677   for ((itr) = (array)->members;                                        \
678        (itr) < (((typeof(*itr)*)(array)->members) + (array)->len);      \
679        (itr)++)
680
681 /**
682  * @def EINA_INARRAY_REVERSE_FOREACH
683  * @brief walks array linearly from tail to head
684  * @param array array object
685  * @param itr the iterator pointer
686  *
687  * @a itr must be a pointer with sizeof(itr*) == array->member_size.
688  *
689  * @warning This is fast as it does direct pointer access, but it will
690  *          not check for @c NULL pointers or invalid array object!
691  *
692  * @warning Do not modify array as you walk it! If that is desired,
693  *          then use eina_inarray_foreach_remove()
694  *
695  * @since 1.2
696  */
697 #define EINA_INARRAY_REVERSE_FOREACH(array, itr)                        \
698   for ((itr) = ((((typeof(*(itr))*)(array)->members) + (array)->len) - 1); \
699        (((itr) >= (typeof(*(itr))*)(array)->members)                    \
700         && ((array)->members != NULL));                                 \
701        (itr)--)
702
703 /**
704  * @}
705  */
706
707 /**
708  * @}
709  */
710
711 /**
712  * @}
713  */
714
715 #endif /*EINA_INARRAY_H_*/