list.h 4.53 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/** A generic list implementation.
 *
 * This is a generic implementation of a list which can store void pointers to
 * arbitrary data. The data itself is not stored or managed by the list.
 *
 * Internally, an array of pointers is used to store the pointers.
 * If needed, this array will grow by realloc().
 *
 * @file
 * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
Steffen Vogel's avatar
Steffen Vogel committed
11
 * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
*
 * VILLAScommon
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
28
29
30
31
 *********************************************************************************/

#pragma once

#include <stdbool.h>
32
#include <sys/types.h>
33
34
35
36
#include <pthread.h>

#include <villas/common.h>

37
38
39
40
#ifdef __cplusplus
extern "C" {
#endif

41
42
43
44
45
46
#define LIST_CHUNKSIZE		16

/** Static list initialization */
#define LIST_INIT_STATIC(l)					\
__attribute__((constructor(105))) static void UNIQUE(__ctor)() {\
	if ((l)->state == STATE_DESTROYED)			\
Steffen Vogel's avatar
Steffen Vogel committed
47
		vlist_init(l);					\
48
49
}								\
__attribute__((destructor(105))) static void UNIQUE(__dtor)() {	\
Steffen Vogel's avatar
Steffen Vogel committed
50
	vlist_destroy(l, NULL, false);				\
51
52
}

Steffen Vogel's avatar
Steffen Vogel committed
53
54
55
#define vlist_length(list)	((list)->length)
#define vlist_at_safe(list, index) ((list)->length > index ? (list)->array[index] : NULL)
#define vlist_at(list, index)	((list)->array[index])
56

Steffen Vogel's avatar
Steffen Vogel committed
57
58
#define vlist_first(list)	vlist_at(list, 0)
#define vlist_last(list)		vlist_at(list, (list)->length-1)
59
60
61
62
63

/** Callback to search or sort a list. */
typedef int (*cmp_cb_t)(const void *, const void *);

/* The list data structure. */
Steffen Vogel's avatar
Steffen Vogel committed
64
struct vlist {
65
	enum state state;	/**< The state of this list. */
66
67
68
69
70
71
72
73
74
75
	void **array;		/**< Array of pointers to list elements */
	size_t capacity;	/**< Size of list::array in elements */
	size_t length;		/**< Number of elements of list::array which are in use */
	pthread_mutex_t lock;	/**< A mutex to allow thread-safe accesses */
};

/** Initialize a list.
 *
 * @param l A pointer to the list data structure.
 */
Steffen Vogel's avatar
Steffen Vogel committed
76
int vlist_init(struct vlist *l);
77
78
79

/** Destroy a list and call destructors for all list elements
 *
Steffen Vogel's avatar
Steffen Vogel committed
80
 * @param free free() all list members during when calling vlist_destroy()
81
82
83
 * @param dtor A function pointer to a desctructor which will be called for every list item when the list is destroyed.
 * @param l A pointer to the list data structure.
 */
Steffen Vogel's avatar
Steffen Vogel committed
84
int vlist_destroy(struct vlist *l, dtor_cb_t dtor, bool free);
85
86

/** Append an element to the end of the list */
Steffen Vogel's avatar
Steffen Vogel committed
87
void vlist_push(struct vlist *l, void *p);
88
89

/** Remove all occurences of a list item */
90
91
92
93
94
void vlist_remove_all(struct vlist *l, void *p);

int vlist_remove(struct vlist *l, size_t idx);

int vlist_insert(struct vlist *l, size_t idx, void *p);
95
96
97
98
99
100
101
102
103
104
105
106

/** Return the first list element which is identified by a string in its first member variable.
 *
 * List elements are pointers to structures of the following form:
 *
 * struct obj {
 *    char *name;
 *    // more members
 * }
 *
 * @see Only possible because of §1424 of http://c0x.coding-guidelines.com/6.7.2.1.html
 */
Steffen Vogel's avatar
Steffen Vogel committed
107
void * vlist_lookup(struct vlist *l, const char *name);
108

Steffen Vogel's avatar
Steffen Vogel committed
109
ssize_t vlist_lookup_index(struct vlist *l, const char *name);
110

111
/** Return the first element of the list for which cmp returns zero */
Steffen Vogel's avatar
Steffen Vogel committed
112
void * vlist_search(struct vlist *l, cmp_cb_t cmp, void *ctx);
113
114

/** Returns the number of occurences for which cmp returns zero when called on all list elements. */
Steffen Vogel's avatar
Steffen Vogel committed
115
int vlist_count(struct vlist *l, cmp_cb_t cmp, void *ctx);
116
117

/** Return 0 if list contains pointer p */
Steffen Vogel's avatar
Steffen Vogel committed
118
int vlist_contains(struct vlist *l, void *p);
119
120

/** Sort the list using the quicksort algorithm of libc */
Steffen Vogel's avatar
Steffen Vogel committed
121
void vlist_sort(struct vlist *l, cmp_cb_t cmp);
122
123

/** Set single element in list */
Steffen Vogel's avatar
Steffen Vogel committed
124
int vlist_set(struct vlist *l, unsigned index, void *value);
125

126
127
128
129
130
/** Return index in list for value.
 *
 * @retval <0 No list entry  matching \p value was found.
 * @retval >=0 Entry \p value was found at returned index.
 */
Steffen Vogel's avatar
Steffen Vogel committed
131
ssize_t vlist_index(struct vlist *l, void *value);
132
133

/** Extend the list to the given length by filling new slots with given value. */
Steffen Vogel's avatar
Steffen Vogel committed
134
void vlist_extend(struct vlist *l, size_t len, void *val);
135

136
137
138
#ifdef __cplusplus
}
#endif