Dymanic array

Overview

Implementation of dymanic array

Example of using:

// typedefs

typedef struct te_vec te_vec;

// structs

struct te_vec;

// global functions

static size_t te_vec_size(const te_vec* vec);
static const void* te_vec_get_immutable(const te_vec* vec, size_t index);
static void* te_vec_get_mutable(te_vec* vec, size_t index);
static const void* te_vec_get_safe_immutable(const te_vec* vec, size_t index, size_t element_size);
static void* te_vec_get_safe_mutable(te_vec* vec, size_t index, size_t element_size);
te_errno te_vec_append(te_vec* vec, const void* element);
te_errno te_vec_append_vec(te_vec* vec, const te_vec* other);
te_errno te_vec_append_array(te_vec* vec, const void* elements, size_t count);
te_errno te_vec_append_str_fmt(te_vec* vec, const char* fmt, ...);
void te_vec_remove(te_vec* vec, size_t start_index, size_t count);
static void te_vec_remove_index(te_vec* vec, size_t index);
static te_errno te_vec_append_array_safe(te_vec* vec, const void* elements, size_t count, size_t element_size);
void te_vec_reset(te_vec* vec);
void te_vec_free(te_vec* vec);
void te_vec_deep_free(te_vec* vec);
te_errno te_vec_append_strarray(te_vec* vec, const char** elements);
static size_t te_vec_get_index(const te_vec* vec, const void* ptr);
te_errno te_vec_split_string(const char* str, te_vec* strvec, char sep, te_bool empty_is_none);
void te_vec_sort(te_vec* vec, int(*)(const void*elt1, const void*elt2) compar);
te_bool te_vec_search(const te_vec* vec, const void* key, int(*)(const void*key, const void*elt) compar, unsigned int* minpos, unsigned int* maxpos);

// macros

#define TE_VEC_APPEND(_te_vec, _val)
#define TE_VEC_APPEND_ARRAY(_te_vec, _elements, _count)
#define TE_VEC_APPEND_RVALUE(_te_vec, _type, _val)
#define TE_VEC_FOREACH(_te_vec, _elem)
#define TE_VEC_GET(_type, _te_vec, _index)
#define TE_VEC_INIT(_type)
#define TE_VEC_INIT_GROW_FACTOR(_type, _grow_factor)
#define te_vec_get(_vec, _index)
#define te_vec_get_safe(_vec, _index, _element_size)

Detailed Documentation

Implementation of dymanic array

Example of using:

// Initialize the dynamic vector to store a value of type int
te_vec vec = TE_VEC_INIT(int)
int number = 42;
...
// Put number into dynamic array
CHECK_RC(TE_VEC_APPEND(&vec, number));
...
// Copy from c array
int numbers[] = {4, 2};
CHECK_RC(te_vec_append_array(&vec, numbers, TE_ARRAY_LEN(numbers)));
...
// Change the first element
TE_VEC_GET(int, &vec, 0) = 100;
...
// Finish work with vector, free the memory.
te_vec_free(&vec);

Copyright (C) 2019-2022 OKTET Labs Ltd. All rights reserved.

Typedefs

typedef struct te_vec te_vec

Dymanic array

Global Functions

static size_t te_vec_size(const te_vec* vec)

Count of elements contains in dynamic array

Parameters:

vec

Dynamic vector

Returns:

Count of elements

te_errno te_vec_append(te_vec* vec, const void* element)

Append one element to the dynamic array

Parameters:

vec

Dymanic vector

element

Element for appending

Returns:

Status code

te_errno te_vec_append_vec(te_vec* vec, const te_vec* other)

Append elements from other dynamic array

Parameters:

vec

Dymanic vector

other

Other dymanic vector

Returns:

Status code

te_errno te_vec_append_array(te_vec* vec, const void* elements, size_t count)

Append elements from C-like array to the dynamic array

Parameters:

vec

Dymanic vector

elements

Elements of array

count

Count of elements

Returns:

Status code

te_errno te_vec_append_str_fmt(te_vec* vec, const char* fmt, ...)

Append a formatted C-string to the dynamic array

Parameters:

vec

Dynamic vector of C-strings

fmt

Format string

Format string arguments

Returns:

Status code

void te_vec_remove(te_vec* vec, size_t start_index, size_t count)

Remove elements from a vector

If the elements of the vector are themselves pointers, they won’t be automatically freed.

Parameters:

vec

Dynamic vector

start_index

Starting index of elements to remove

count

Number of elements to remove

static void te_vec_remove_index(te_vec* vec, size_t index)

Remove an element from a vector

Parameters:

vec

Dynamic vector

index

Index of a element to remove

static te_errno te_vec_append_array_safe(te_vec* vec, const void* elements, size_t count, size_t element_size)

Safe version of te_vec_append_array

Parameters:

vec

Dymanic vector

elements

Elements of array

count

Count of elements

element_size

Size of one element in elements

Returns:

Status code

void te_vec_reset(te_vec* vec)

Reset dynamic array (makes it empty), memory is not freed

Parameters:

vec

Dynamic vector

void te_vec_free(te_vec* vec)

Cleanup dynamic array and storage memory

Parameters:

vec

Dynamic vector

void te_vec_deep_free(te_vec* vec)

Free the dynamic array along with its elements which must be pointers deallocatable by free()

Parameters:

vec

Dynamic vector of pointers

Returns:

Status code

te_errno te_vec_append_strarray(te_vec* vec, const char** elements)

Append to a dynamic array of strings

Parameters:

vec

Dynamic vector to append the array of strings to

elements

NULL terminated array of strings

Returns:

Status code

static size_t te_vec_get_index(const te_vec* vec, const void* ptr)

Return an index of an element of vec pointed to by ptr.

Returns:

Zero-based index. The result is undefined if ptr is not pointing to the actual vector data

te_errno te_vec_split_string(const char* str, te_vec* strvec, char sep, te_bool empty_is_none)

Split a string into chunks separated by sep.

The copies of the chunks are pushed into the strvec. (the memory is owned by the vector, i.e. it must be later freed by e.g. te_vec_deep_free()).

The element size of strvec must be sizeof(char *).

Adjacent separators are never skipped, so e.g. ':: :’ would be split into four chunks using colon as a separator. The only special case is an empty string which may be treated as no chunks depending on empty_is_none.

Parameters:

str

String to split

strvec

Target vector for string chunks. The original contents is not destroyed, new items are added to the end.

sep

Separator character

empty_is_none

If TRUE, empty string is treated as having no chunks (so strvec is not changed). Otherwise, an empty string is treated as having a single empty chunk.

Returns:

Status code

void te_vec_sort(te_vec* vec, int(*)(const void*elt1, const void*elt2) compar)

Sort the elements of vec in place according to compar.

Parameters:

vec

Vector to sort

compar

Comparison function (as for qsort())

te_bool te_vec_search(const te_vec* vec, const void* key, int(*)(const void*key, const void*elt) compar, unsigned int* minpos, unsigned int* maxpos)

Search a sorted vector vec for an item equal to key using compar as a comparison function.

The function implements binary search, however unlike C standard bsearch() it can be reliably used on non-unique matches, because it returns the lowest and the highest indices of matching elements.

Mind the order of arguments. compar expects the first argument to be a key and the second argument to be an array element, for a compatibility with bsearch(). However, the order of arguments of the function itself is reverse wrt bsearch(): the vector goes first and the key follows it for consistency with other vector functions. For cases where the key has the same structure as the array element, this should not matter.

The vector must be sorted in a way compatible with compar, i.e. by using te_vec_sort() with the same compar, however, the comparison functions need not to be truly identical: the search comparison function may treat more elements as equal than the sort comparison.

Parameters:

vec

Vector to search in

key

Key to search

compar

Comparison function (as for bsearch())

minpos

The lowest index of a matching element.

maxpos

The highest index of a matchin element. Any of minpos and maxpos may be NULL. If they are both NULL, the function just checks for an existence of a matching element.

Returns:

TRUE iff an element matching key is found.

Macros

#define TE_VEC_APPEND(_te_vec, _val)

Add element to the vector’s tail

Parameters:

_te_vec

Dynamic vector

_val

New element

Returns:

Status code

#define TE_VEC_APPEND_ARRAY(_te_vec, _elements, _count)

Append elements from C-like array to the dynamic array (safe version)

Parameters:

_te_vec

Dymanic vector

_elements

Elements of array

_count

Count of elements

Returns:

Status code

#define TE_VEC_APPEND_RVALUE(_te_vec, _type, _val)

Add element to the vector’s tail

Parameters:

_te_vec

Dynamic vector

_type

Element type

_val

New element

Returns:

Status code

#define TE_VEC_FOREACH(_te_vec, _elem)

For each element in vector

Example:

struct netinterface {
    int index;
    const char *name;
};

te_vec vec = TE_VEC_INIT(struct netinterface);
... // Fill vector with values

struct netinterface *netif;
TE_VEC_FOREACH(&vec, netif)
{
     printf("interface '%s' have index %d", netif->name, netif->index);
}

Parameters:

_te_vec

Dynamic vector

_elem

Pointer of type contain in vector

#define TE_VEC_GET(_type, _te_vec, _index)

Access for element in array

Parameters:

_type

Type of element

_te_vec

Dynamic vector

_index

Index of element

Returns:

Element of array

#define TE_VEC_INIT(_type)

Initialization from type only

#define TE_VEC_INIT_GROW_FACTOR(_type, _grow_factor)

Initialization from type and custom grow factor and type

#define te_vec_get(_vec, _index)

Access to a pointer of element in array

Parameters:

_vec

Dynamic vector

_index

Index of element

Returns:

Pointer to element

#define te_vec_get_safe(_vec, _index, _element_size)

Safe version of te_vec_get

Parameters:

_vec

Dynamic vector

_index

Index of element

_element_size

Expected size of type in array

Returns:

Pointer to element