aboutsummaryrefslogtreecommitdiffstats
path: root/libsimple/memelem.h
blob: bce3e0cfe0a08af88fd93ad3855c7a62ae27bf35 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/* See LICENSE file for copyright and license details. */


/**
 * Finds the first element in an array, the comparison is case-sensitive
 * 
 * @param   haystack   The array of bytes to search
 * @param   nhaystack  The length of `haystack`, divided by `needle`
 * @param   needle     The substring to search for
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a minimal offset such that,
 *                     `!memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`,
 *                     `NULL` if no such offset exists
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
void *libsimple_memelem(const void *, size_t, const void *, size_t);
#ifndef memelem
# define memelem libsimple_memelem
#endif


/**
 * Finds the first element in an array, the comparison is case-sensitive
 * 
 * This function is optimised for instances where it is already
 * known that there is at least one occurence; if there is no
 * occurence of the specified value in the specified array, its
 * behaviour is undefined
 * 
 * @param   haystack   The array of bytes to search
 * @param   needle     The substring to search for
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a minimal offset such that,
 *                     `!memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __returns_nonnull__, __warn_unused_result__)))
void *libsimple_rawmemelem(const void *, const void *, size_t); /* TODO man */
#ifndef rawmemelem
# define rawmemelem libsimple_rawmemelem
#endif


/**
 * Finds the first element in an array, the comparison is case-sensitive
 * 
 * @param   haystack   The array of bytes to search
 * @param   nhaystack  The length of `haystack`, divided by `needle`
 * @param   needle     The substring to search for
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a minimal offset such that,
 *                     `!memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`,
 *                     `(void *)&((char *)haystack)[nhaystack * nneedle]`
 *                     if no such offset exists
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
void *libsimple_memelemscan(const void *, size_t, const void *, size_t);
#ifndef memelemscan
# define memelemscan libsimple_memelemscan
#endif


/**
 * Finds the last element in an array, the comparison is case-sensitive
 * 
 * @param   haystack   The array of bytes to search
 * @param   nhaystack  The length of `haystack`, divided by `needle`
 * @param   needle     The substring to search for
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a maximal offset such that,
 *                     `!memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`,
 *                     `NULL` if no such offset exists
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
void *libsimple_memrelem(const void *, size_t, const void *, size_t);
#ifndef memrelem
# define memrelem libsimple_memrelem
#endif


/**
 * Finds the last element in an array, the comparison is case-sensitive
 * 
 * This function is optimised for instances where it is already
 * known that there is at least one occurence; if there is no
 * occurence of the specified value in the specified array, its
 * behaviour is undefined
 * 
 * @param   haystack   The array of bytes to search
 * @param   nhaystack  The length of `haystack`, divided by `needle`
 * @param   needle     The substring to search for
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a maximal offset such that,
 *                     `!memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __returns_nonnull__, __warn_unused_result__)))
void *libsimple_rawmemrelem(const void *, size_t, const void *, size_t);
#ifndef rawmemrelem
# define rawmemrelem libsimple_rawmemrelem
#endif


/**
 * Finds the first element in an array that is different from
 * the specified element, the comparison is case-sensitive
 * 
 * @param   haystack   The array of bytes to search
 * @param   nhaystack  The length of `haystack`, divided by `needle`
 * @param   needle     The substring to skip over
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a minimal offset such that,
 *                     `memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`,
 *                     `NULL` if no such offset exists
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
void *libsimple_memelem_inv(const void *, size_t, const void *, size_t);
#ifndef memelem_inv
# define memelem_inv libsimple_memelem_inv
#endif


/**
 * Finds the first element in an array that is different from
 * the specified element, the comparison is case-sensitive
 * 
 * This function is optimised for instances where it is already
 * known that there is at least one occurence; if there is no
 * occurence of any value other than the specified value in the
 * specified array, its behaviour is undefined
 * 
 * @param   haystack   The array of bytes to search
 * @param   needle     The substring to skip over
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a minimal offset such that,
 *                     `memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __returns_nonnull__, __warn_unused_result__)))
void *libsimple_rawmemelem_inv(const void *, const void *, size_t);
#ifndef rawmemelem_inv
# define rawmemelem_inv libsimple_rawmemelem_inv
#endif


/**
 * Finds the first element in an array that is different from
 * the specified element, the comparison is case-sensitive
 * 
 * @param   haystack   The array of bytes to search
 * @param   nhaystack  The length of `haystack`, divided by `needle`
 * @param   needle     The substring to skip over
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a minimal offset such that,
 *                     `memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`,
 *                     `(void *)&((char *)haystack)[nhaystack * nneedle]`
 *                     if no such offset exists
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
void *libsimple_memelemscan_inv(const void *, size_t, const void *, size_t);
#ifndef memelemscan_inv
# define memelemscan_inv libsimple_memelemscan_inv
#endif


/**
 * Finds the last element in an array that is different from
 * the specified element, the comparison is case-sensitive
 * 
 * @param   haystack   The array of bytes to search
 * @param   nhaystack  The length of `haystack`, divided by `needle`
 * @param   needle     The substring to skip over
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a maximal offset such that,
 *                     `memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`,
 *                     `NULL` if no such offset exists
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
void *libsimple_memrelem_inv(const void *, size_t, const void *, size_t);
#ifndef memrelem_inv
# define memrelem_inv libsimple_memrelem_inv
#endif


/**
 * Finds the last element in an array that is different from
 * the specified element, the comparison is case-sensitive
 * 
 * This function is optimised for instances where it is already
 * known that there is at least one occurence; if there is no
 * occurence of any value other than the specified value in the
 * specified array, its behaviour is undefined
 * 
 * @param   haystack   The array of bytes to search
 * @param   nhaystack  The length of `haystack`, divided by `needle`
 * @param   needle     The substring to skip over
 * @param   nneedle    The length of `needle`
 * @return             `haystack` with a maximal offset such that,
 *                     `memcmp(r, needle, nneedle)` where `r` is the
 *                     returned pointer and such that `(r - haystack) % nneedle == 0`
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __returns_nonnull__, __warn_unused_result__)))
void *libsimple_rawmemrelem_inv(const void *, size_t, const void *, size_t);
#ifndef rawmemrelem_inv
# define rawmemrelem_inv libsimple_rawmemrelem_inv
#endif


/**
 * Fills an array with a number of copies of an item
 * 
 * @param   buf     The array to fill
 * @param   item    The element to fill `buf` with
 * @param   size    The size of `item`
 * @param   nitems  The number of copies to fill `buf` with
 * @return          `&buf[nelems * size]`
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
void *libsimple_mempsetelem(void *__buf, const void *__item, size_t __size, size_t __nitems);
#ifndef mempsetelem
# define mempsetelem libsimple_mempsetelem
#endif


/**
 * Fills an array with a number of copies of an item
 * 
 * @param   buf     The array to fill
 * @param   item    The element to fill `buf` with
 * @param   size    The size of `item`
 * @param   nitems  The number of copies to fill `buf` with
 * @return          `buf`
 */
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *libsimple_memsetelem(void *__buf, const void *__item, size_t __size, size_t __nitems)
{ return __item = libsimple_mempsetelem(__buf, __item, __size, __nitems), __buf; }
#ifndef memsetelem
# define memsetelem libsimple_memsetelem
#endif


/**
 * Replace all instances of an element in an array of
 * elements with another element
 * 
 * @param   s      The array
 * @param   old    The value of the elements to replace
 * @param   new    The value to replace the elements with
 * @param   n      The length of `s`, measured in elements
 * @param   width  The size of each element
 * @return         `(void *)&((char *)s)[n * width]`
 */
void *libsimple_memreplaceelem(void *restrict __s_, const void *__old_, const void *__new_, size_t __n, size_t __width);
#ifndef memreplaceelem
# define memreplaceelem libsimple_memreplaceelem
#endif