1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
16 #ifndef SQUIRRELJME_LIST_H
17 #define SQUIRRELJME_LIST_H
21 #include "sjme/stdTypes.h"
22 #include "sjme/tokenUtils.h"
23 #include "sjme/comparator.h"
24 #include "sjme/alloc.h"
25 #include "sjme/error.h"
26 #include "sjme/debug.h"
30 #ifndef SJME_CXX_IS_EXTERNED
31 #define SJME_CXX_IS_EXTERNED
32 #define SJME_CXX_SQUIRRELJME_LIST_H
34 #endif /* #ifdef SJME_CXX_IS_EXTERNED */
35 #endif /* #ifdef __cplusplus */
37 /*--------------------------------------------------------------------------*/
40 * Determines the name of the given list.
42 * @param type The type used.
43 * @param numPointerStars The number of pointer stars.
46 #define SJME_LIST_NAME(type, numPointerStars) \
47 SJME_TOKEN_PASTE_PP(sjme_list_, SJME_TOKEN_PASTE_PP(type, \
48 SJME_TOKEN_SINGLE(SJME_TOKEN_STARS_C##numPointerStars)))
51 * Declares a list type.
53 * @param type The type to use for the list values.
54 * @param numPointerStars The number of pointer stars.
57 #define SJME_LIST_DECLARE(type, numPointerStars) \
58 /** A list of @c type. */ \
59 typedef struct SJME_LIST_NAME(type, numPointerStars) \
61 /** The length of this type. */ \
64 /** The element size of this type. */ \
65 sjme_jint elementSize; \
67 /** The element offset of this type. */ \
68 sjme_jint elementOffset; \
70 /** The elements in the list. */ \
71 SJME_TOKEN_TYPE(type, numPointerStars) \
72 elements[sjme_flexibleArrayCount]; \
73 } SJME_LIST_NAME(type, numPointerStars)
76 * Calculates the static size of a list.
78 * @param type The element type of the list.
79 * @param numPointerStars The number of pointer stars.
80 * @param count The length of the list.
81 * @return The resultant length of the list.
84 #define SJME_SIZEOF_LIST(type, numPointerStars, count) \
85 (sizeof(SJME_LIST_NAME(type, numPointerStars)) + \
86 (offsetof(SJME_LIST_NAME(type, numPointerStars), elements) - \
87 offsetof(SJME_LIST_NAME(type, numPointerStars), elements)) + \
88 (sizeof(SJME_TOKEN_TYPE(type, numPointerStars)) * (size_t)(count)))
90 /** List of @c sjme_jbyte. */
91 SJME_LIST_DECLARE(sjme_jbyte
, 0);
93 /** List of @c sjme_jubyte. */
94 SJME_LIST_DECLARE(sjme_jubyte
, 0);
96 /** List of @c sjme_jshort. */
97 SJME_LIST_DECLARE(sjme_jshort
, 0);
99 /** List of @c sjme_jchar. */
100 SJME_LIST_DECLARE(sjme_jchar
, 0);
102 /** List of @c sjme_jint. */
103 SJME_LIST_DECLARE(sjme_jint
, 0);
105 /** List of @c sjme_jint* . */
106 SJME_LIST_DECLARE(sjme_jint
, 1);
108 /** List of @c sjme_juint . */
109 SJME_LIST_DECLARE(sjme_juint
, 0);
111 /** List of @c sjme_lpstr . */
112 SJME_LIST_DECLARE(sjme_lpstr
, 0);
114 /** List of @c sjme_lpcstr . */
115 SJME_LIST_DECLARE(sjme_lpcstr
, 0);
117 /** List of @c sjme_pointer . */
118 SJME_LIST_DECLARE(sjme_pointer
, 0);
120 /** List of @c sjme_cchar . */
121 SJME_LIST_DECLARE(sjme_cchar
, 0);
123 /** List of @c sjme_pointerLen . */
124 SJME_LIST_DECLARE(sjme_pointerLen
, 0);
126 /** List of @c sjme_intPointer . */
127 SJME_LIST_DECLARE(sjme_intPointer
, 0);
129 /** List of @c sjme_jobject . */
130 SJME_LIST_DECLARE(sjme_jobject
, 0);
133 typedef sjme_list_sjme_jint sjme_list_void
;
135 /** Cast to void list. */
136 #define SJME_AS_LIST_VOID(x) ((sjme_list_void*)(x))
138 /** Cast to void list. */
139 #define SJME_AS_LISTP_VOID(x) ((sjme_list_void**)(x))
142 * Allocates a given list generically.
144 * @param inPool The pool to allocate within.
145 * @param inLength The length of the list.
146 * @param outList The output list.
147 * @param elementSize The size of the list elements.
148 * @param elementOffset The offset of elements in the list.
149 * @param pointerCheck A check to see if it is a valid pointer.
150 * @return Any resultant error code, if any.
153 sjme_errorCode
sjme_list_allocR(
154 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
155 sjme_attrInPositive sjme_jint inLength
,
156 sjme_attrOutNotNull sjme_pointer
* outList
,
157 sjme_attrInPositive sjme_jint elementSize
,
158 sjme_attrInPositive sjme_jint elementOffset
,
159 sjme_attrInValue sjme_jint pointerCheck
160 SJME_DEBUG_ONLY_COMMA SJME_DEBUG_DECL_FILE_LINE_FUNC_OPTIONAL
);
163 * Allocates the given list without setting any of the values.
165 * @param inPool The pool to allocate within.
166 * @param inLength The list length.
167 * @param outList The resultant list.
168 * @param type The list type.
169 * @param numPointerStars The number of pointer stars.
170 * @return Any error state.
173 #define sjme_list_alloc(inPool, inLength, outList, type, numPointerStars) \
174 sjme_list_allocR((inPool), (inLength), \
175 (sjme_pointer*)(outList), \
176 sizeof(SJME_TOKEN_TYPE(type, numPointerStars)), \
177 offsetof(SJME_LIST_NAME(type, numPointerStars), elements), \
178 sizeof(**(outList)) SJME_DEBUG_ONLY_COMMA SJME_DEBUG_FILE_LINE_FUNC)
181 * Allocates a given list generically.
183 * @param inPool The pool to allocate within.
184 * @param inNewLength The new list length.
185 * @param inOldList The list to copy from.
186 * @param outNewList The resultant list.
187 * @param elementSize The size of the list elements.
188 * @param elementOffset The offset of elements in the list.
189 * @param pointerCheck A check to see if it is a valid pointer.
190 * @return Any resultant error code, if any.
193 sjme_errorCode
sjme_list_copyR(
194 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
195 sjme_attrInPositive sjme_jint inNewLength
,
196 sjme_attrInNotNull sjme_pointer inOldList
,
197 sjme_attrOutNotNull sjme_pointer
* outNewList
,
198 sjme_attrInPositive sjme_jint elementSize
,
199 sjme_attrInPositive sjme_jint elementOffset
,
200 sjme_attrInValue sjme_jint pointerCheck
201 SJME_DEBUG_ONLY_COMMA SJME_DEBUG_DECL_FILE_LINE_FUNC_OPTIONAL
);
204 * Allocates a new list that is a copy of the old list.
206 * @param inPool The pool to allocate within.
207 * @param inNewLength The new list length.
208 * @param inOldList The list to copy from.
209 * @param outNewList The resultant list.
210 * @param type The list type.
211 * @param numPointerStars The number of pointer stars.
212 * @return Any error state.
215 #define sjme_list_copy(inPool, inNewLength, inOldList, outNewList, type, \
217 sjme_list_copyR((inPool), (inNewLength), (inOldList), \
218 (sjme_pointer*)(outNewList), \
219 sizeof(SJME_TOKEN_TYPE(type, numPointerStars)), \
220 offsetof(SJME_LIST_NAME(type, numPointerStars), elements), \
221 sizeof(**(outNewList)) SJME_DEBUG_ONLY_COMMA SJME_DEBUG_FILE_LINE_FUNC)
224 * Directly initializes a list.
226 * @param inLength The length of the list.
227 * @param outList The output list.
228 * @param elementSize The size of the list elements.
229 * @param elementOffset The offset of elements in the list.
230 * @param pointerCheck A check to see if it is a valid pointer.
231 * @return Any resultant error code, if any.
234 sjme_errorCode
sjme_list_directInitR(
235 sjme_attrInPositive sjme_jint inLength
,
236 sjme_attrOutNotNull sjme_pointer outList
,
237 sjme_attrInPositive sjme_jint elementSize
,
238 sjme_attrInPositive sjme_jint elementOffset
,
239 sjme_attrInValue sjme_jint pointerCheck
);
242 * Directly initializes a list.
244 * @param inLength The input list length.
245 * @param outList The resultant list information.
246 * @param type The type used in the list.
247 * @param numPointerStars The number of pointer stars used.
248 * @return Any resultant error.
251 #define sjme_list_directInit(inLength, outList, type, numPointerStars) \
252 sjme_list_directInitR((inLength), \
253 (sjme_pointer)(outList), \
254 sizeof(SJME_TOKEN_TYPE(type, numPointerStars)), \
255 offsetof(SJME_LIST_NAME(type, numPointerStars), elements), \
259 * Create a new list with the given set of arguments.
261 * @param inPool The pool to allocate within.
262 * @param elementSize The element size.
263 * @param rootElementSize The root element size.
264 * @param elementOffset The element offset.
265 * @param pointerCheck Pointer check value.
266 * @param basicTypeId The type code of the input.
267 * @param numPointerStars The number of pointer stars.
268 * @param length The length of the list.
269 * @param outList The resultant list.
270 * @param inElements The list elements.
271 * @return Any resultant error code.
274 sjme_errorCode
sjme_list_newAR(
275 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
276 sjme_attrInPositive sjme_jint elementSize
,
277 sjme_attrInPositive sjme_jint rootElementSize
,
278 sjme_attrInPositive sjme_jint elementOffset
,
279 sjme_attrInValue sjme_jint pointerCheck
,
280 sjme_attrInNotNull sjme_basicTypeId basicTypeId
,
281 sjme_attrInPositive sjme_jint numPointerStars
,
282 sjme_attrInPositive sjme_jint length
,
283 sjme_attrOutNotNull sjme_pointer
* outList
,
284 sjme_attrInNotNull sjme_pointer inElements
);
287 * Create a new list with the given set of arguments.
289 * @param inPool The pool to allocate within.
290 * @param type The element type.
291 * @param numPointerStars The number of pointer stars.
292 * @param length The length of the list.
293 * @param outList The resultant list.
294 * @param inElements The list elements.
295 * @return Any resultant error code.
298 #define sjme_list_newA(inPool, type, numPointerStars, \
299 inLength, outList, inElements) \
300 sjme_list_newAR((inPool), \
301 sizeof(SJME_TOKEN_TYPE(type, numPointerStars)), \
303 offsetof(SJME_LIST_NAME(type, numPointerStars), elements), \
304 sizeof(**(outList)), SJME_TYPEOF_BASIC(type), (numPointerStars), \
305 (inLength), (sjme_pointer*)(outList), (sjme_pointer)(inElements))
308 * Create a new list with the given set of arguments.
310 * @param inPool The pool to allocate within.
311 * @param elementSize The element size.
312 * @param rootElementSize The root element size.
313 * @param elementOffset The element offset.
314 * @param pointerCheck Pointer check value.
315 * @param basicTypeId The type code of the input.
316 * @param numPointerStars The number of pointer stars.
317 * @param length The length of the list.
318 * @param outList The resultant list.
319 * @param ... The list elements.
320 * @return Any resultant error code.
323 sjme_errorCode
sjme_list_newVR(
324 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
325 sjme_attrInPositive sjme_jint elementSize
,
326 sjme_attrInPositive sjme_jint rootElementSize
,
327 sjme_attrInPositive sjme_jint elementOffset
,
328 sjme_attrInValue sjme_jint pointerCheck
,
329 sjme_attrInNotNull sjme_basicTypeId basicTypeId
,
330 sjme_attrInPositive sjme_jint numPointerStars
,
331 sjme_attrInPositive sjme_jint length
,
332 sjme_attrOutNotNull sjme_pointer
* outList
,
336 * Create a new list with the given set of arguments.
338 * @param inPool The pool to allocate within.
339 * @param type The element type.
340 * @param numPointerStars The number of pointer stars.
341 * @param length The length of the list.
342 * @param outList The resultant list.
343 * @param ... The list elements.
344 * @return Any resultant error code.
347 #define sjme_list_newV(inPool, type, numPointerStars, \
348 inLength, outList, ...) \
349 sjme_list_newVR((inPool), \
350 sizeof(SJME_TOKEN_TYPE(type, numPointerStars)), \
352 offsetof(SJME_LIST_NAME(type, numPointerStars), elements), \
353 sizeof(**(outList)), SJME_TYPEOF_BASIC(type), (numPointerStars), \
354 (inLength), (sjme_pointer*)(outList), __VA_ARGS__)
357 * Create a new list with the given set of arguments.
359 * @param inPool The pool to allocate within.
360 * @param elementSize The element size.
361 * @param rootElementSize The root element size.
362 * @param elementOffset The element offset.
363 * @param pointerCheck Pointer check value.
364 * @param basicType The type code of the input.
365 * @param numPointerStars The number of pointer stars.
366 * @param length The length of the list.
367 * @param outList The resultant list.
368 * @param elements The list elements.
369 * @return Any resultant error code.
372 sjme_errorCode
sjme_list_newVAR(
373 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
374 sjme_attrInPositive sjme_jint elementSize
,
375 sjme_attrInPositive sjme_jint rootElementSize
,
376 sjme_attrInPositive sjme_jint elementOffset
,
377 sjme_attrInValue sjme_jint pointerCheck
,
378 sjme_attrInNotNull sjme_basicTypeId basicType
,
379 sjme_attrInPositive sjme_jint numPointerStars
,
380 sjme_attrInPositive sjme_jint length
,
381 sjme_attrOutNotNull sjme_pointer
* outList
,
385 * Create a new list with the given set of arguments.
387 * @param inPool The pool to allocate within.
388 * @param type The element type.
389 * @param numPointerStars The number of pointer stars.
390 * @param length The length of the list.
391 * @param outList The resultant list.
392 * @param elements The list elements.
393 * @return Any resultant error code.
396 #define sjme_list_newVA(inPool, type, numPointerStars, \
397 inLength, outList, elements) \
398 sjme_list_newVAR((inPool), \
399 sizeof(SJME_TOKEN_TYPE(type, numPointerStars)), \
401 offsetof(SJME_LIST_NAME(type, numPointerStars), elements), \
402 sizeof(**(outList)), SJME_TYPEOF_BASIC(type), (numPointerStars), \
403 (inLength), (sjme_pointer*)(outList), (elements))
406 * Flattens argc/argv style lists into a single allocation where the pointers
407 * to the arguments point within the same allocation link. The main purpose of
408 * this is to have to not have to handle going through the list to free
409 * all the containing pointers accordingly.
411 * @param inPool The pool to allocate within.
412 * @param outList The output list.
413 * @param argC The argument count.
414 * @param argV The arguments.
415 * @return Any resultant error.
418 sjme_errorCode
sjme_list_flattenArgCV(
419 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
420 sjme_attrOutNotNull sjme_list_sjme_lpstr
** outList
,
421 sjme_attrInPositive sjme_jint argC
,
422 sjme_attrInNotNull sjme_lpcstr
* argV
);
425 * Flattens a string which is split by NUL (@c aNULbNULcNULNUL ) into a list.
427 * @param inPool The pool to allocate within.
428 * @param outList The resultant list.
429 * @param inNulString The input string.
430 * @return Any resultant error.
433 sjme_errorCode
sjme_list_flattenArgNul(
434 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
435 sjme_attrOutNotNull sjme_list_sjme_lpcstr
** outList
,
436 sjme_attrInNotNull sjme_lpcstr inNulString
);
439 * Searches the given list for the given element.
441 * @param inList The list to look within.
442 * @param comparator The comparator to compare between entries.
443 * @param findWhat The element to search for within the list.
444 * @param outIndex The resultant output index or @c -1 if not found.
445 * @return Any resultant orr, if any.
448 sjme_errorCode
sjme_list_search(
449 sjme_attrInNotNull sjme_pointer inList
,
450 sjme_attrInNotNull sjme_comparator comparator
,
451 sjme_attrInNotNull sjme_cpointer findWhat
,
452 sjme_attrOutNotNull sjme_jint
* outIndex
);
455 * Binary searches the given list, requires that it is sorted.
457 * @param inList The list to search within.
458 * @param comparator The comparison to use for entries.
459 * @param findWhat The element to search for within the list.
460 * @param outIndex The resultant index if found, or
461 * will be @begincode (-(insertion point) - 1) @endcode if it was not found
463 * @return Any resultant error, if any.
464 * @see sjme_list_searchInsertionPoint
467 sjme_errorCode
sjme_list_searchBinary(
468 sjme_attrInNotNull sjme_pointer inList
,
469 sjme_attrInNotNull sjme_comparator comparator
,
470 sjme_attrInNotNull sjme_cpointer findWhat
,
471 sjme_attrOutNotNull sjme_jint
* outIndex
);
474 * Reverses the insertion point operation to either map to one or to get
475 * the insertion point.
477 * @param index The index to map.
478 * @return The resultant insertion point.
481 #define sjme_list_searchInsertionPoint(index) \
485 * Searches the given list in reverse for the given element.
487 * @param inList The list to look within.
488 * @param comparator The comparator to compare between entries.
489 * @param findWhat The element to search for within the list.
490 * @param outIndex The resultant output index or @c -1 if not found.
491 * @return Any resultant orr, if any.
494 sjme_errorCode
sjme_list_searchReverse(
495 sjme_attrInNotNull sjme_pointer inList
,
496 sjme_attrInNotNull sjme_comparator comparator
,
497 sjme_attrInNotNull sjme_cpointer findWhat
,
498 sjme_attrOutNotNull sjme_jint
* outIndex
);
501 * Sorts the elements of the given list.
503 * @param inList The list of items to search.
504 * @param comparator The comparator to use when comparing entries.
505 * @return Any resultant error, if any.
508 sjme_errorCode
sjme_list_sort(
509 sjme_attrInNotNull sjme_pointer inList
,
510 sjme_attrInNotNull sjme_comparator comparator
);
512 /*--------------------------------------------------------------------------*/
516 #ifdef SJME_CXX_SQUIRRELJME_LIST_H
518 #undef SJME_CXX_SQUIRRELJME_LIST_H
519 #undef SJME_CXX_IS_EXTERNED
520 #endif /* #ifdef SJME_CXX_SQUIRRELJME_LIST_H */
521 #endif /* #ifdef __cplusplus */
523 #endif /* SQUIRRELJME_LIST_H */