123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- /*
- * category: [data structure]
- * apply status: framework
- * edit status: not
- * build status: windows&linux
- * description:
- */
- #ifndef ARRAY_H
- #define ARRAY_H
- #pragma once
- #include "config.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <stdarg.h>
- #include <stdlib.h>
- #include "memutil.h"
- typedef struct array_header_t array_header_t;
- /** An opaque array type */
- struct array_header_t {
- /** The amount of memory allocated for each element of the array */
- int elt_size;
- /** The number of active elements in the array */
- int nelts;
- /** The number of elements already allocated in the array */
- int nalloc;
- /** The elements in the array, start address.*/
- char *elts;
- };
- /**
- * Determine if the array is empty (either NULL or having no elements)
- * @param a The array to check
- * @return True if empty, False otherwise
- */
- TOOLKIT_API int array_empty(const array_header_t *a);
- /**
- * Create an array
- * @param nelts the number of elements in the initial array
- * @param elt_size The size of each element in the array.
- * @return The new array
- */
- TOOLKIT_API array_header_t *array_make(int nelts, int elt_size);
- /**
- * destroy an array
- */
- TOOLKIT_API void array_free(array_header_t *arr);
- /**
- * Add a new element to an array (as a first-in, last-out stack)
- * @param arr The array to add an element to.
- * @return Location for the new element in the array.
- * @remark If there are no free spots in the array, then this function will
- * allocate new space for the new element.
- */
- TOOLKIT_API void *array_push(array_header_t *arr);
- /** A helper macro for accessing a member of an array.
- *
- * @param ary the array
- * @param i the index into the array to return
- * @param type the type of the objects stored in the array
- *
- * @return the item at index i
- */
- #define ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i])
- /** A helper macro for pushing elements into an array.
- *
- * @param ary the array
- * @param type the type of the objects stored in the array
- *
- * @return the location where the new object should be placed
- */
- #define ARRAY_PUSH(ary,type) (*((type *)array_push(ary)))
- /** A helper function to exchange two elem
- *
- * @param ary the array
- * @param type the type of the objects stored in the array
- *
- * note: element type must be single type(not struct)
- */
- #define ARRAY_XCHG(ary, x, y, type) \
- do { \
- type tmp; \
- tmp = ARRAY_IDX(ary, x, type); \
- ARRAY_IDX(ary, x, type) = ARRAY_IDX(ary, y, type); \
- ARRAY_IDX(ary, y, type) = tmp; \
- } while (0)
- #define ARRAY_XCHG_STRUCT(ary, i, j, type) \
- do { \
- type* ti = &ARRAY_IDX(ary, i, type); \
- type* tj = &ARRAY_IDX(ary, j, type); \
- type tmp; \
- memcpy(&tmp, ti, sizeof(type)); \
- memcpy(ti, tj, sizeof(type)); \
- memcpy(tj, &tmp, sizeof(type)); \
- } while(0)
- /** A helper by exchange position x with tail, witch type is a simple type
- *
- * @param ary the array
- * @param type the type of the objects stored in the array
- *
- * note: element type must be single type(not struct)
- */
- #define ARRAY_XCHG_TAIL(ary, x, type) \
- do { \
- if ((x) < (ary->nelts - 1)) { \
- ARRAY_XCHG(ary, x, ary->nelts - 1, type); \
- } \
- } while(0)
- /** A helper by exchange position x with tail, witch type is a struct type */
- #define ARRAY_XCHG_TAIL_STRUCT(ary, x, type) \
- do { \
- if ((x) < (ary->nelts - 1)) { \
- ARRAY_XCHG_STRUCT(ary, x, ary->nelts - 1, type); \
- } \
- } while (0)
- /** A helper delete x by exchange value with tail and pop out */
- #define ARRAY_DEL(ary, x, type) \
- ARRAY_XCHG_TAIL(ary, x, type); \
- array_pop(ary);
- /** A helper delete x by exchange value with tail and pop out, for struct type */
- #define ARRAY_DEL_STRUCT(ary, i, type) \
- ARRAY_XCHG_TAIL_STRUCT(ary, i, type); \
- array_pop(ary);
- /** helper for walk through each element */
- #define ARRAY_FOR_EACH_ENTRY(pos, i, ary, type) \
- for (i = ary->nelts-1; pos = ARRAY_IDX(ary, i, type), i >= 0; --i)
- /** helper for walk through each element, can delete current pos */
- #define ARRAY_FOR_EACH_ENTRY_SAFE ARRAY_FOR_EACH_ENTRY
- /**
- * Remove an element from an array (as a first-in, last-out stack)
- * @param arr The array to remove an element from.
- * @return Location of the element in the array.
- * @remark If there are no elements in the array, NULL is returned.
- */
- TOOLKIT_API void * array_pop(array_header_t *arr);
- /**
- * Remove all elements from an array.
- * @param arr The array to remove all elements from.
- * @remark As the underlying storage is allocated from a pool, no
- * memory is freed by this operation, but is available for reuse.
- */
- TOOLKIT_API void array_clear(array_header_t *arr);
- /**
- * Concatenate two arrays together
- * @param dst The destination array, and the one to go first in the combined
- * array
- * @param src The source array to add to the destination array
- */
- TOOLKIT_API void array_cat(array_header_t *dst,const array_header_t *src);
- /**
- * Copy the entire array
- * @param arr The array to copy
- * @return An exact copy of the array passed in
- * @remark The alternate apr_array_copy_hdr copies only the header, and arranges
- * for the elements to be copied if (and only if) the code subsequently
- * does a push or arraycat.
- */
- TOOLKIT_API array_header_t * array_copy(const array_header_t *arr);
- /**
- * Reserves a minimum length of storage, allocating space if necessary
- *
- */
- TOOLKIT_API void array_reserve(array_header_t *arr, int cnt);
- /**
- * destroy an array, and destry each element by free
- */
- static __inline void array_free2(array_header_t *arr)
- {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- free(ARRAY_IDX(arr, i, void*));
- }
- array_free(arr);
- }
- TOOLKIT_API void toolkit_array_free2(array_header_t *arr);
- #ifdef __cplusplus
- } // extern "C" {
- #endif
- #endif // ARRAY_H
|