1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2019 Tobias Kortkamp <tobik@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 #pragma once
29 
30 struct Array;
31 struct ArrayIterator;
32 struct diff;
33 struct Mempool;
34 typedef int (*ArrayCompareFn)(const void *, const void *, void *);
35 
36 struct Array *array_new(void);
37 struct Array *array_from_array(const void *[], size_t);
38 void array_append(struct Array *, const void *);
39 struct diff *array_diff(struct Array *, struct Array *, struct Mempool *, ArrayCompareFn, void *);
40 void array_free(struct Array *);
41 void *array_get(struct Array *, size_t);
42 ssize_t array_find(struct Array *, const void *, ArrayCompareFn, void *);
43 void array_insert(struct Array *, size_t, const void *);
44 void *array_remove(struct Array *, size_t);
45 void array_join(struct Array *, struct Array *[], size_t);
46 size_t array_len(struct Array *);
47 void *array_pop(struct Array *);
48 void array_set(struct Array *, size_t, const void *);
49 void array_sort(struct Array *, ArrayCompareFn, void *);
50 void array_truncate(struct Array *);
51 void array_truncate_at(struct Array *array, size_t);
52 
53 struct ArrayIterator *array_iterator(struct Array *, ssize_t, ssize_t);
54 void array_iterator_cleanup(struct ArrayIterator **);
55 bool array_iterator_next(struct ArrayIterator **, size_t *, void **, void **);
56 
57 #define ARRAY(...) \
58 	array_from_array((const void *[]){__VA_ARGS__}, sizeof((const void *[]){__VA_ARGS__})/sizeof(const void *))
59 
60 #define ARRAY_JOIN(ARRAY, ...) __ARRAY_JOIN(ARRAY, GENSYM(__array_join__), __VA_ARGS__)
61 #define __ARRAY_JOIN(ARRAY, ARRAYS, ...) do { \
62 	struct Array *ARRAYS[] = { __VA_ARGS__ }; \
63 	array_join(ARRAY, ARRAYS, nitems(ARRAYS)); \
64 } while(0);
65 
66 #define ARRAY_FOREACH_SLICE(ARRAY, A, B, TYPE, VAR) \
67 	ITERATOR_FOREACH(Array, array, ARRAY, A, B, TYPE, void **, VAR, NULL, void *, void **, GENSYM(VAR), NULL)
68 #define ARRAY_FOREACH(ARRAY, TYPE, VAR) \
69 	ARRAY_FOREACH_SLICE(ARRAY, 0, -1, TYPE, VAR)
70