Skip to content

Commit 3442eaa

Browse files
committed
arrt: Add.
A consolidated array type. Streamlines & standardizes arrays relative to the lower level arr module.
1 parent 202a4ea commit 3442eaa

File tree

6 files changed

+203
-2
lines changed

6 files changed

+203
-2
lines changed

src/csnip/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ configure_file(csnip_conf.h.in csnip_conf.h)
125125
set(public_headers
126126
${CMAKE_CURRENT_BINARY_DIR}/csnip_conf.h
127127
arr.h
128+
arrt.h
128129
cext.h
129130
clopts.h
130131
err.h

src/csnip/arrt.h

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#ifndef CSNIP_ARRT_H
2+
#define CSNIP_ARRT_H
3+
4+
/** @file arrt.h
5+
* @brief Dynamic arrays container type
6+
* @defgroup arrt Dynamic arrays container type
7+
* @{
8+
*
9+
* @brief Dynamic arrays container type.
10+
*
11+
* Defines a container type for dynamic arrays, and wraps the
12+
* csnip_arr_* macros so that the container is used. Often, this
13+
* is simpler than using csnip's lower level (but more flexible)
14+
* arr interface. Another advantage over using arr directly is
15+
* that it standardizes the members of the array. For a type T,
16+
* the container type is of the form:
17+
* ```
18+
* struct {
19+
* T* a; // array itself
20+
* size_t n; // size of the array in members
21+
* size_t cap; // capacity of the array
22+
* };
23+
* ```
24+
* Having the same standardized form in many places reduces
25+
* cognitive load.
26+
*/
27+
28+
#include <stddef.h>
29+
30+
#include <csnip/arr.h>
31+
32+
/** Initialize an array.
33+
*
34+
* arrt version of @sa csnip_arr_Init()
35+
*/
36+
#define csnip_arrt_Init(arrp, initial_cap, err) \
37+
csnip_arr_init((arrp)->a, (arrp)->n, (arrp)->cap, (initial_cap), (err))
38+
39+
/** Reserve space for members to be added.
40+
*
41+
* arrt version of @sa csnip_arr_Reserve()
42+
*/
43+
#define csnip_arrt_Reserve(arrp, least_cap, err) \
44+
csnip_arr_Reserve((arrp)->a, (arrp)->n, (arrp)->cap, (least_cap), (err))
45+
46+
/** Append a new value at the end of the array.
47+
*
48+
* arrt version of @sa csnip_arr_Push()
49+
*/
50+
#define csnip_arrt_Push(arrp, value, err) \
51+
csnip_arr_Push((arrp)->a, (arrp)->n, (arrp)->cap, (value), (err))
52+
53+
/** Delete the value at the end of the array.
54+
*
55+
* arrt version of @sa csnip_arr_Pop()
56+
*/
57+
#define csnip_arrt_Pop(arrp, err) \
58+
csnip_arr_Pop(((arrp)->a, (arrp)->n, (arrp)->cap, (err))
59+
60+
/** Insert a new member at a given position in the array.
61+
*
62+
* arrt version of @sa csnip_arr_InsertAt()
63+
*/
64+
#define csnip_arrt_InsertAt(arrp, index, val, err) \
65+
csnip_arr_InsertAt((arrp)->a, (arrp)->n, (arrp)->cap, \
66+
(index), (val), (err))
67+
68+
/** Remove an array member at a given index.
69+
*
70+
* arrt version of @sa csnip_arr_DeleteAt()
71+
*/
72+
#define csnip_arrt_DeleteAt(arrp, index, err) \
73+
csnip_arr_DeleteAt((arrp)->a, (arrp)->n, (arrp)->cap, (index), (err))
74+
75+
/** Free backend storage and reduce size to 0.
76+
*
77+
* arrt version of @sa csnip_arr_Deinit()
78+
*/
79+
#define csnip_arrt_Deinit(arrp) \
80+
csnip_arr_Free((arrp)->a, (arrp)->n, (arrp)->cap)
81+
82+
/** Define an array type.
83+
*
84+
* Creates a struct typedef for an array type, consisting of the
85+
* members `a` (the pointer to the first member), `n`, the array
86+
* size, and `cap`, the array capacity.
87+
*
88+
* @param arr_type
89+
* name of the type to assign.
90+
*
91+
* @param elem_type
92+
* type of the elements.
93+
*/
94+
#define CSNIP_ARRT_DEF_TYPE(arr_type, elem_type) \
95+
typedef struct arr_type ## _s { \
96+
elem_type* a; \
97+
size_t n; \
98+
size_t cap; \
99+
} arr_type;
100+
101+
/** Declare the array type.
102+
*
103+
* As @sa CSNIP_ARRT_DEF_TYPE, but don't define the struct, only
104+
* declare it as an opaque type.
105+
*/
106+
#define CSNIP_ARRT_DECL_TYPE(arr_type, elem_type) \
107+
struct arr_type ## _s; \
108+
typedef struct arr_type ## _s arr_type;
109+
110+
/** Declare the array functions. */
111+
#define CSNIP_ARRT_DECL_FUNCS(scope, prefix, arr_type, val_type) \
112+
CSNIP_ARR_DECL_FUNCS(scope, prefix, val_type, \
113+
args(arr_type*, int*))
114+
115+
/** Define the array functions.
116+
*
117+
* The functions defined are the same as in the lower level arr
118+
* module, @sa CSNIP_ARR_DEF_FUNCS.
119+
*/
120+
#define CSNIP_ARRT_DEF_FUNCS(scope, prefix, arr_type, val_type) \
121+
CSNIP_ARR_DEF_FUNCS(scope, prefix, val_type, \
122+
args(arr_type* A, int* err), \
123+
A->a, A->n, A->cap, *err)
124+
125+
/** @} */
126+
127+
#endif /* CSNIP_ARRT_H */
128+
129+
#if defined(CSNIP_SHORT_NAMES) && !defined(CSNIP_ARRT_HAVE_SHORT_NAMES)
130+
#define arrt_Init csnip_arr_Init
131+
#define arrt_Reserve csnip_arr_Reserve
132+
#define arrt_Push csnip_arr_Push
133+
#define arrt_Pop csnip_arr_Pop
134+
#define arrt_InsertAt csnip_arr_InsertAt
135+
#define arrt_DeleteAt csnip_arr_DeleteAt
136+
#define arrt_Free csnip_arr_Free
137+
#define CSNIP_ARR_HAVE_SHORT_NAMES
138+
#endif /* CSNIP_SHORT_NAMES && !CSNIP_ARRT_HAVE_SHORT_NAMES */

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
set(tests_c
22
arr_test0.c
33
arr_test1.c
4+
arrt_test0.c
5+
arrt_test1.c
46
clopts_test0.c
57
cext_test0.c
68
err_test0.c

test/arr_test1.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
#include <stdio.h>
33
#include <stdlib.h>
44

5+
/* If the USE_ARRT_INSTEAD macro is set, test the arrt interface instead
6+
* of arr. This is set in arrt_test1.c before including this file whole
7+
* sale here. Avoids duplicating this code.
8+
*/
9+
#ifndef USE_ARRT_INSTEAD
10+
511
#include <csnip/arr.h>
6-
#include <csnip/cext.h>
712

813
typedef struct {
914
int* a;
@@ -19,7 +24,7 @@ CSNIP_ARR_DECL_FUNCS(
1924
)
2025

2126
CSNIP_ARR_DEF_FUNCS(
22-
static csnip_cext_unused, // static
27+
static, // static
2328
IntArr_, // scope
2429
int, // value type
2530
args(IntArr* A, int* err), // gen_args
@@ -29,6 +34,25 @@ CSNIP_ARR_DEF_FUNCS(
2934
*err // error return
3035
)
3136

37+
#else
38+
39+
#include <csnip/arrt.h>
40+
41+
CSNIP_ARRT_DEF_TYPE(IntArr, int)
42+
CSNIP_ARRT_DECL_FUNCS(
43+
static, // scope
44+
IntArr_, // prefix
45+
IntArr, // array type
46+
int) // value type
47+
48+
CSNIP_ARRT_DEF_FUNCS(
49+
static, // static
50+
IntArr_, // scope
51+
IntArr, // array type
52+
int) // value type
53+
54+
#endif
55+
3256
static bool test_reserve()
3357
{
3458
IntArr A;

test/arrt_test0.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* This is pretty much a copy-paste of arr_test0.c with the minor top
2+
* changes
3+
*/
4+
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
8+
#include <csnip/arrt.h>
9+
#include <csnip/cext.h>
10+
11+
CSNIP_ARRT_DEF_TYPE(IntArray, int)
12+
CSNIP_ARRT_DEF_FUNCS(csnip_cext_unused static, IntArray_, IntArray, int)
13+
14+
int main()
15+
{
16+
printf("Experiments with IntArray types.\n");
17+
IntArray Ax;
18+
IntArray_init(&Ax, NULL, 16);
19+
for (int i = 0; i < 128; ++i) {
20+
IntArray_push(&Ax, NULL, 3*i - 128);
21+
}
22+
printf("Array contains %zu elements.\n", Ax.n);
23+
printf("Array has capacity %zu.\n", Ax.cap);
24+
const int N = 3;
25+
for(int i = 0; i < N; ++i) {
26+
printf("[%d] %d\n", i, Ax.a[i]);
27+
}
28+
puts("...");
29+
for(int i = 0; i < N; ++i) {
30+
printf("[%zu] %d\n", Ax.n - i - 1, Ax.a[Ax.n - i - 1]);
31+
}
32+
IntArray_deinit(&Ax, NULL);
33+
return 0;
34+
}

test/arrt_test1.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define USE_ARRT_INSTEAD
2+
#include "arr_test1.c"

0 commit comments

Comments
 (0)