@@@ man wip
[mLib] / struct / darray.3
CommitLineData
d1836466 1.\" -*-nroff-*-
2.de VS
3.sp 1
4.RS
5.nf
6.ft B
7..
8.de VE
9.ft R
10.fi
11.RE
12.sp 1
13..
14.de hP
15.IP
16.ft B
17\h'-\w'\\$1\ 'u'\\$1\ \c
18.ft P
19..
20.ie t .ds o \(bu
21.el .ds o o
fbf20b5b 22.TH darray 3 "21 October 1999" "Straylight/Edgeware" "mLib utilities library"
d1836466 23.SH "NAME"
24darray \- dense, dynamically resizing arrays
25.\" @DA_INIT
26.\" @DA_DECL
27.\" @DA_CREATE
28.\" @DA_DESTROY
29.\" @DA_ENSURE
30.\" @DA_SHUNT
31.\" @DA_TIDY
85bb21f7 32.\" @DA_RESET
d1836466 33.\" @DA
34.\" @DA_LEN
35.\" @DA_SPARE
36.\" @DA_OFFSET
37.\" @DA_INCLUDE
38.\" @DA_EXTEND
39.\" @DA_UNSAFE_EXTEND
40.\" @DA_SLIDE
41.\" @DA_UNSAFE_SLIDE
85bb21f7 42.\" @DA_SHRINK
43.\" @DA_UNSAFE_SHRINK
44.\" @DA_UNSLIDE
45.\" @DA_UNSAFE_UNSLIDE
706bf01d 46.\" @DA_FIRST
47.\" @DA_LAST
d1836466 48.\" @DA_PUSH
49.\" @DA_POP
50.\" @DA_UNSHIFT
51.\" @DA_SHIFT
52.\" @DAEXC_UFLOW
53.\" @DAEXC_OFLOW
54.\" @da_ensure
55.\" @da_shunt
56.\" @da_tidy
57.SH "SYNOPSIS"
58.nf
59.B "#include <mLib/darray.h>"
60
adec5584 61.ta 2n
4729aa69 62.B "typedef struct {"
adec5584
MW
63.B " size_t sz, len, off;"
64.B " unsigned push, unshift;"
65.B " arena *a;"
4729aa69
MW
66.B "} da_base;"
67
68.B "#define DA_INIT ..."
69
70.B "#define DAEXC_UFLOW EXC_ALLOCN(EXC_MLIB, ...)"
71.B "#define DAEXC_OFLOW EXC_ALLOCN(EXC_MLIB, ...)"
72
bcb99985 73.BI DA_DECL( type_v ", " type );
bcb99985 74.BI "void DA_CREATE(" type_v " *" a );
75.BI "void DA_DESTROY(" type_v " *" a );
d1836466 76
bcb99985 77.BI "void DA_ENSURE(" type_v " *" a ", size_t " n );
78.BI "void DA_SHUNT(" type_v " *" a ", size_t " n );
79.BI "void DA_TIDY(" type_v " *" a );
80.BI "void DA_RESET(" type_v " *" a );
d1836466 81
bcb99985 82.IB type " *DA(" type_v " *" a );
83.BI "size_t DA_LEN(" type_v " *" a );
84.BI "size_t DA_SPARE(" type_v " *" a );
85.BI "size_t DA_OFFSET(" type_v " *" a );
86.BI "void DA_INCLUDE(" type_v " *" a ", size_t " i );
85bb21f7 87
bcb99985 88.BI "void DA_EXTEND(" type_v " *" a ", long " n );
89.BI "void DA_SHRINK(" type_v " *" a ", long " n );
90.BI "void DA_SLIDE(" type_v " *" a ", long " n );
91.BI "void DA_UNSLIDE(" type_v " *" a ", long " n );
85bb21f7 92
bcb99985 93.BI "void DA_UNSAFE_EXTEND(" type_v " *" a ", long " n );
94.BI "void DA_UNSAFE_SHRINK(" type_v " *" a ", long " n );
95.BI "void DA_UNSAFE_SLIDE(" type_v " *" a ", long " n );
96.BI "void DA_UNSAFE_UNSLIDE(" type_v " *" a ", long " n );
d1836466 97
706bf01d 98.IB type " DA_FIRST(" type_v " *" a );
99.IB type " DA_LAST(" type_v " *" a );
bcb99985 100.BI "void DA_PUSH(" type_v " *" a ", " type " " x );
101.IB type " DA_POP(" type_v " *" a );
102.BI "void DA_UNSHIFT(" type_v " *" a ", " type " " x );
103.IB type " DA_SHIFT(" type_v " *" a );
d1836466 104
105.BI "void *da_ensure(da_base *" b ", void *" v ", size_t " sz ", size_t " n );
106.BI "void *da_shunt(da_base *" b ", void *" v ", size_t " sz ", size_t " n );
107.BI "void *da_tidy(da_base *" b ", void *" v ", size_t " sz );
108.fi
109.SH "DESCRIPTION"
110The
111.B <mLib/darray.h>
d0053e2e 112header file declares a collection of types, macros and functions which
113implement dynamically resizing arrays.
d1836466 114.PP
115The macros described here may evaluate their arguments multiple times
116unless otherwise specified.
117.SS "Creation and destruction"
118Each element type must have its own array
119type declared using the
120.B DA_DECL
121macro. Calling
122.VS
bcb99985 123.BI DA_DECL( type_v ", " type );
d1836466 124.VE
125Declares a new dynamic array type
bcb99985 126.I type_v
d1836466 127whose elements have type
128.IR type .
129.PP
bcb99985 130It is conventional to form the name of an array type by appending
131.RB ` _v '
132to the base type name. If the base type is a standard type, or is
133declared separately from the array, it's also conventional to declare a
134macro with the same name as the array type only in uppercase which may
135be used to prevent multiple declarations, e.g.,
136.VS
137#ifndef FOO_V
138# define FOO_V
cededfbe 139 DA_DECL(foo_v, foo);
bcb99985 140#endif
141.VE
d1836466 142The macro
143.B DA_INIT
144is a valid static initializer for all types of dynamic arrays. For
145cases where this isn't appropriate, a dynamic array may be initialized
146using the macro
8f7d402a 147.BR DA_CREATE ,
d1836466 148passing it the address of the array.
149.PP
150Arrays may be disposed of using the
151.B DA_DESTROY
152macro, which again takes the address of the array.
153.SS "Storage allocation"
154.PP
155Space for new array elements may be reserved using the
156.B DA_ENSURE
157and
158.B DA_SHUNT
159macros, which reserve space at the end and beginning of the array
160respectively. Both macros take two arguments: the address of an array
161object and the number of spare elements required.
162.PP
163Neither of these macros actually extends the array; both merely allocate
164memory for the array to extend itself into. Use the macros
165.B DA_EXTEND
166and
167.B DA_SLIDE
168to actually increase the bounds of the array.
169.PP
170Note that when space is reserved, all the array elements might move.
171You should be careful not to depend on the addresses of array elements.
172If sufficient storage cannot be allocated, the exception
173.B EXC_NOMEM
174is thrown (see
175.BR exc (3)).
176.PP
177The macro
178.B DA_TIDY
179takes one argument: the address of a dynamic array. It minimizes the
180amount of memory used by the array. This is a useful function to call
181when the array's size has finally settled down.
85bb21f7 182.PP
183The macro
184.B DA_RESET
185accepts the address of an array. It reduces the length of the array to
186zero. No storage is deallocated. Resetting arrays might not be a good
187idea if the objects in the array are dynamically allocated.
d1836466 188.SS "Accessing array elements"
189If
190.I a
191is the address of a dynamic array object, then
192.BI DA( a )
193is the base address of the actual array. The elements are stored
194contiguously starting at this address. An element at index
195.I i
196may be referenced using the syntax
8f7d402a 197.BI DA( a )[ i ]\fR.
d1836466 198.PP
199The number of elements in the array
200.I a
201is given by
202.BI DA_LEN( a )\fR.
203An integer array index
204.I i
205is
206.I valid
207if 0 \(<=
208.I i
209<
210.BI DA_LEN( a )\fR.
211.PP
212There may be some spare slots at the end of the array. In particular,
213after a call to
214.BI DA_ENSURE( a ", " n )
215there will be at least
216.I n
217spare slots. The number of spare slots at the end of the array may be
218obtained as
219.BI DA_SPARE( a )\fR.
220.PP
221Similarly, there may be spare slots before the start of the array. In
222particular, after a call to
223.BI DA_SHUNT( a ", " n )
224there will be at least
225.I n
226spare slots. The number of spare slots before the start of the array
227may be obtained as
228.BI DA_OFFSET( a )\fR.
229.PP
230The call
231.BI DA_INCLUDE( a ", " i )
232ensures that the array's bounds include the index
233.I i
234by extending the array if necessary. The exception
235.B EXC_NOMEM
236is thrown if there isn't enough memory to do this.
237.PP
238The array's bounds may be extended by
239.I n
240slots by calling
241.BI DA_EXTEND( a ", " n )\fR.
242The integer
243.I n
244must be less than
245.BI DA_SPARE( a )\fR;
246if this is not the case then the exception
247.B DAEXC_OFLOW
248is thrown.
249Note that
250.I n
251may be negative to reduce the bounds of the array: in this case it must
252be greater than
253.BI \-DA_LEN( a )
254or the exception
255.B DAEXC_UFLOW
256is thrown. The macro
257.B DA_UNSAFE_EXTEND
258does the same job, but performs no error checking.
259.PP
260The macro
261.BI DA_SLIDE( a ", " n )
262offsets the array elements by
263.IR n .
264If
265.I n
266is positive, the array elements are slid upwards, to higher-numbered
267indices; if
268.I n
269is negative, the elements are slid downwards. Precisely, what happens
270is that elements which used to have index
271.I i
272\-
273.I n
274now have index
275.IR i .
276The exception
277.B DAEXC_OFLOW
278is thrown if
279.I n
280>
281.BI DA_OFFSET( a )\fR;
282.B DAEXC_UFLOW
283is thrown if
284.I n
285<
286.BI \-DA_LEN( a )\fR.
287The macro
288.B DA_UNSAFE_SLIDE
289does the same job, only without the error checking.
85bb21f7 290.PP
291The macros
292.B DA_SHRINK
293and
294.B DA_UNSLIDE
295do the same things as
296.B DA_EXTEND
297and
298.B DA_SLIDE
299respectively, except that they interpret the sign of their second
300arguments in the opposite way. This is useful if the argument is
301unsigned (e.g., if it's based on
cededfbe 302.BR DA_LEN ).
303There are unsafe versions of both these macros too.
d1836466 304.SS "Stack operations"
305Dynamic arrays support Perl-like stack operations. Given an array
306(pointer)
307.I a
308and an object of the array's element type
309.I x
310the following operations are provided:
311.TP
312.BI DA_PUSH( a ", " x )
313Add
314.I x
315to the end of the array, increasing the array size by one.
316.TP
317.IB x " = DA_POP(" a )
318Remove the final element of the array, assigning
319.I x
320its value and decreasing the array size by one.
321.TP
322.BI DA_UNSHIFT( a ", " x )
323Insert
324.I x
325at the beginning of the array, shifting all the elements up one place
326and increasing the array size by one.
327.TP
328.IB x " = DA_SHIFT(" a )
329Remove the first element of the array, assigning
330.I x
331its value, shifting all the subsequent array items down one place and
332decreasing the array size by one.
333.PP
334The operations
335.B DA_PUSH
336and
337.B DA_UNSHIFT
338can fail due to lack of memory, in which case
339.B EXC_NOMEM
340is thrown. The operations
341.B DA_POP
342and
343.B DA_SHIFT
344can fail because the array is empty, in which case
345.B DAEXC_UFLOW
346is thrown.
706bf01d 347.PP
348The operations
349.B DA_FIRST
350and
351.B DA_LAST
352are lvalues referring to the first and last elements in the array
353respectively. They are unsafe if the array is empty.
d1836466 354.SS "Low-level details"
355This section describes low-level details of the dynamic array
356implementation. You should try to avoid making use of this information
357if you can, since the interface may change in later library versions.
358In particular, more subtleties may be added which low-level access will
359miss.
360.PP
361Dynamic arrays are structures with the format
362.VS
bcb99985 363.BI "typedef struct " type_v " {"
d1836466 364.B " da_base b;"
365.BI " " type " *v;"
bcb99985 366.BI "} " type_v ";"
d1836466 367.VE
368The pointer
369.B v
370indicates the current base of the array. This will move in the
371allocated space as a result of
372.B DA_SHIFT
373and
374.B DA_UNSHIFT
375(and
376.BR DA_SLIDE )
377operations.
378.PP
379The
380.B da_base
381structure contains the following elements:
382.TP
383.B "size_t sz"
384The number of allocated slots from
385.B v
386onwards.
387.TP
388.B "size_t len"
389The number of items considered to be in the array. The allocated space
390is usually larger than this.
391.TP
392.B "size_t off"
393The number of allocated slots preceding
394.BR v .
395The total number of allocated items is therefore
396.B sz
397+
398.BR off .
399.TP
400.B "unsigned push"
401The number of items pushed or ensured since the last array expansion.
402.TP
403.B "unsigned unshift"
404The number of items unshifted or shunted since the last array expansion.
405.PP
406The
407.B push
408and
409.B unshift
410members are used by the expansion routines to decide how to allocate
411free space before and after the array elements following a reallocation.
412The other members should be fairly self-explanatory.
413.PP
414The reallocation routines
415.BR da_ensure ,
416.B da_shunt
417and
418.B da_tidy
419have a regular interface. They're a bit
420strange, though, because they have to deal with lots of different types
421of arrays. The arguments they take are:
422.TP
423.BI "da_base *" b
424Pointer to the
425.B da_base
426member of the array block.
427.TP
428.BI "void *" v
429The array base pointer from the array block (i.e., the
430.B v
431member).
432.TP
433.BI "size_t " sz
434The element size for the array.
435.TP
436.BI "size_t " n
437(For
438.B da_ensure
439and
440.B da_shunt
441only.) The number of spare slots required.
442.PP
443The functions may modify the base structure, and return a newly
444allocated (or at least repositioned) array base pointer, or throw
445.B EXC_NOMEM
446if there's not enough memory.
447.PP
448The three functions behave as follows:
449.TP
450.B da_ensure
451Ensure that there are at least
452.I n
453spare slots after the end of the array.
454.TP
455.B da_shunt
456Ensure that there are at least
457.I n
458spare slots preceding the start of the array.
459.TP
460.B da_tidy
461Reallocate the array to use the smallest amount of memory possible.
462.SH "SEE ALSO"
463.BR exc (3),
464.BR mLib (3).
465.SH "AUTHOR"
9b5ac6ff 466Mark Wooding, <mdw@distorted.org.uk>