chiark / gitweb /
Minor edits.
[mLib] / man / 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
22.TH darray 3 "21 October 1999" mLib
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
32.\" @DA
33.\" @DA_LEN
34.\" @DA_SPARE
35.\" @DA_OFFSET
36.\" @DA_INCLUDE
37.\" @DA_EXTEND
38.\" @DA_UNSAFE_EXTEND
39.\" @DA_SLIDE
40.\" @DA_UNSAFE_SLIDE
41.\" @DA_PUSH
42.\" @DA_POP
43.\" @DA_UNSHIFT
44.\" @DA_SHIFT
45.\" @DAEXC_UFLOW
46.\" @DAEXC_OFLOW
47.\" @da_ensure
48.\" @da_shunt
49.\" @da_tidy
50.SH "SYNOPSIS"
51.nf
52.B "#include <mLib/darray.h>"
53
54.BI DA_DECL( atype ", " type );
55.IB atype " " a " = DA_INIT;"
56.BI "void DA_CREATE(" atype " *" a );
57.BI "void DA_DESTROY(" atype " *" a );
58
59.BI "void DA_ENSURE(" atype " *" a ", size_t " n );
60.BI "void DA_SHUNT(" atype " *" a ", size_t " n );
61.BI "void DA_TIDY(" atype " *" a );
62
63.IB type " *DA(" atype " *" a );
64.BI "size_t DA_LEN(" atype " *" a );
65.BI "size_t DA_SPARE(" atype " *" a );
66.BI "size_t DA_OFFSET(" atype " *" a );
67.BI "void DA_INCLUDE(" atype " *" a ", size_t " i );
68.BI "void DA_EXTEND(" atype " *" a ", long " n );
69.BI "void DA_UNSAFE_EXTEND(" atype " *" a ", long " n );
70.BI "void DA_SLIDE(" atype " *" a ", long " n );
71.BI "void DA_UNSAFE_SLIDE(" atype " *" a ", long " n );
72
73.BI "void DA_PUSH(" atype " *" a ", " type " " x );
74.IB type " DA_POP(" atype " *" a );
75.BI "void DA_UNSHIFT(" atype " *" a ", " type " " x );
76.IB type " DA_SHIFT(" atype " *" a );
77
78.BI "void *da_ensure(da_base *" b ", void *" v ", size_t " sz ", size_t " n );
79.BI "void *da_shunt(da_base *" b ", void *" v ", size_t " sz ", size_t " n );
80.BI "void *da_tidy(da_base *" b ", void *" v ", size_t " sz );
81.fi
82.SH "DESCRIPTION"
83The
84.B <mLib/darray.h>
85declares a collection of types, macros and functions which implement
86dynamically resizing arrays.
87.PP
88The macros described here may evaluate their arguments multiple times
89unless otherwise specified.
90.SS "Creation and destruction"
91Each element type must have its own array
92type declared using the
93.B DA_DECL
94macro. Calling
95.VS
96.BI DA_DECL( atype ", " type );
97.VE
98Declares a new dynamic array type
99.I atype
100whose elements have type
101.IR type .
102.PP
103The macro
104.B DA_INIT
105is a valid static initializer for all types of dynamic arrays. For
106cases where this isn't appropriate, a dynamic array may be initialized
107using the macro
108.BR DA_INIT ,
109passing it the address of the array.
110.PP
111Arrays may be disposed of using the
112.B DA_DESTROY
113macro, which again takes the address of the array.
114.SS "Storage allocation"
115.PP
116Space for new array elements may be reserved using the
117.B DA_ENSURE
118and
119.B DA_SHUNT
120macros, which reserve space at the end and beginning of the array
121respectively. Both macros take two arguments: the address of an array
122object and the number of spare elements required.
123.PP
124Neither of these macros actually extends the array; both merely allocate
125memory for the array to extend itself into. Use the macros
126.B DA_EXTEND
127and
128.B DA_SLIDE
129to actually increase the bounds of the array.
130.PP
131Note that when space is reserved, all the array elements might move.
132You should be careful not to depend on the addresses of array elements.
133If sufficient storage cannot be allocated, the exception
134.B EXC_NOMEM
135is thrown (see
136.BR exc (3)).
137.PP
138The macro
139.B DA_TIDY
140takes one argument: the address of a dynamic array. It minimizes the
141amount of memory used by the array. This is a useful function to call
142when the array's size has finally settled down.
143.SS "Accessing array elements"
144If
145.I a
146is the address of a dynamic array object, then
147.BI DA( a )
148is the base address of the actual array. The elements are stored
149contiguously starting at this address. An element at index
150.I i
151may be referenced using the syntax
152.BI DA( a )[ i \fR.
153.PP
154The number of elements in the array
155.I a
156is given by
157.BI DA_LEN( a )\fR.
158An integer array index
159.I i
160is
161.I valid
162if 0 \(<=
163.I i
164<
165.BI DA_LEN( a )\fR.
166.PP
167There may be some spare slots at the end of the array. In particular,
168after a call to
169.BI DA_ENSURE( a ", " n )
170there will be at least
171.I n
172spare slots. The number of spare slots at the end of the array may be
173obtained as
174.BI DA_SPARE( a )\fR.
175.PP
176Similarly, there may be spare slots before the start of the array. In
177particular, after a call to
178.BI DA_SHUNT( a ", " n )
179there will be at least
180.I n
181spare slots. The number of spare slots before the start of the array
182may be obtained as
183.BI DA_OFFSET( a )\fR.
184.PP
185The call
186.BI DA_INCLUDE( a ", " i )
187ensures that the array's bounds include the index
188.I i
189by extending the array if necessary. The exception
190.B EXC_NOMEM
191is thrown if there isn't enough memory to do this.
192.PP
193The array's bounds may be extended by
194.I n
195slots by calling
196.BI DA_EXTEND( a ", " n )\fR.
197The integer
198.I n
199must be less than
200.BI DA_SPARE( a )\fR;
201if this is not the case then the exception
202.B DAEXC_OFLOW
203is thrown.
204Note that
205.I n
206may be negative to reduce the bounds of the array: in this case it must
207be greater than
208.BI \-DA_LEN( a )
209or the exception
210.B DAEXC_UFLOW
211is thrown. The macro
212.B DA_UNSAFE_EXTEND
213does the same job, but performs no error checking.
214.PP
215The macro
216.BI DA_SLIDE( a ", " n )
217offsets the array elements by
218.IR n .
219If
220.I n
221is positive, the array elements are slid upwards, to higher-numbered
222indices; if
223.I n
224is negative, the elements are slid downwards. Precisely, what happens
225is that elements which used to have index
226.I i
227\-
228.I n
229now have index
230.IR i .
231The exception
232.B DAEXC_OFLOW
233is thrown if
234.I n
235>
236.BI DA_OFFSET( a )\fR;
237.B DAEXC_UFLOW
238is thrown if
239.I n
240<
241.BI \-DA_LEN( a )\fR.
242The macro
243.B DA_UNSAFE_SLIDE
244does the same job, only without the error checking.
245.SS "Stack operations"
246Dynamic arrays support Perl-like stack operations. Given an array
247(pointer)
248.I a
249and an object of the array's element type
250.I x
251the following operations are provided:
252.TP
253.BI DA_PUSH( a ", " x )
254Add
255.I x
256to the end of the array, increasing the array size by one.
257.TP
258.IB x " = DA_POP(" a )
259Remove the final element of the array, assigning
260.I x
261its value and decreasing the array size by one.
262.TP
263.BI DA_UNSHIFT( a ", " x )
264Insert
265.I x
266at the beginning of the array, shifting all the elements up one place
267and increasing the array size by one.
268.TP
269.IB x " = DA_SHIFT(" a )
270Remove the first element of the array, assigning
271.I x
272its value, shifting all the subsequent array items down one place and
273decreasing the array size by one.
274.PP
275The operations
276.B DA_PUSH
277and
278.B DA_UNSHIFT
279can fail due to lack of memory, in which case
280.B EXC_NOMEM
281is thrown. The operations
282.B DA_POP
283and
284.B DA_SHIFT
285can fail because the array is empty, in which case
286.B DAEXC_UFLOW
287is thrown.
288.SS "Low-level details"
289This section describes low-level details of the dynamic array
290implementation. You should try to avoid making use of this information
291if you can, since the interface may change in later library versions.
292In particular, more subtleties may be added which low-level access will
293miss.
294.PP
295Dynamic arrays are structures with the format
296.VS
297.BI "typedef struct " atype " {"
298.B " da_base b;"
299.BI " " type " *v;"
300.BI "} " atype ";"
301.VE
302The pointer
303.B v
304indicates the current base of the array. This will move in the
305allocated space as a result of
306.B DA_SHIFT
307and
308.B DA_UNSHIFT
309(and
310.BR DA_SLIDE )
311operations.
312.PP
313The
314.B da_base
315structure contains the following elements:
316.TP
317.B "size_t sz"
318The number of allocated slots from
319.B v
320onwards.
321.TP
322.B "size_t len"
323The number of items considered to be in the array. The allocated space
324is usually larger than this.
325.TP
326.B "size_t off"
327The number of allocated slots preceding
328.BR v .
329The total number of allocated items is therefore
330.B sz
331+
332.BR off .
333.TP
334.B "unsigned push"
335The number of items pushed or ensured since the last array expansion.
336.TP
337.B "unsigned unshift"
338The number of items unshifted or shunted since the last array expansion.
339.PP
340The
341.B push
342and
343.B unshift
344members are used by the expansion routines to decide how to allocate
345free space before and after the array elements following a reallocation.
346The other members should be fairly self-explanatory.
347.PP
348The reallocation routines
349.BR da_ensure ,
350.B da_shunt
351and
352.B da_tidy
353have a regular interface. They're a bit
354strange, though, because they have to deal with lots of different types
355of arrays. The arguments they take are:
356.TP
357.BI "da_base *" b
358Pointer to the
359.B da_base
360member of the array block.
361.TP
362.BI "void *" v
363The array base pointer from the array block (i.e., the
364.B v
365member).
366.TP
367.BI "size_t " sz
368The element size for the array.
369.TP
370.BI "size_t " n
371(For
372.B da_ensure
373and
374.B da_shunt
375only.) The number of spare slots required.
376.PP
377The functions may modify the base structure, and return a newly
378allocated (or at least repositioned) array base pointer, or throw
379.B EXC_NOMEM
380if there's not enough memory.
381.PP
382The three functions behave as follows:
383.TP
384.B da_ensure
385Ensure that there are at least
386.I n
387spare slots after the end of the array.
388.TP
389.B da_shunt
390Ensure that there are at least
391.I n
392spare slots preceding the start of the array.
393.TP
394.B da_tidy
395Reallocate the array to use the smallest amount of memory possible.
396.SH "SEE ALSO"
397.BR exc (3),
398.BR mLib (3).
399.SH "AUTHOR"
400Mark Wooding, <mdw@nsict.org>