X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/dd3c57bc8cac59e0d657ee665ce462988d27d714..18c831dcd0ae4d660c70ccac69d27ed2a97851be:/darray.3 diff --git a/darray.3 b/darray.3 deleted file mode 100644 index 8f7953c..0000000 --- a/darray.3 +++ /dev/null @@ -1,455 +0,0 @@ -.\" -*-nroff-*- -.de VS -.sp 1 -.RS -.nf -.ft B -.. -.de VE -.ft R -.fi -.RE -.sp 1 -.. -.de hP -.IP -.ft B -\h'-\w'\\$1\ 'u'\\$1\ \c -.ft P -.. -.ie t .ds o \(bu -.el .ds o o -.TH darray 3 "21 October 1999" "Straylight/Edgeware" "mLib utilities library" -.SH "NAME" -darray \- dense, dynamically resizing arrays -.\" @DA_INIT -.\" @DA_DECL -.\" @DA_CREATE -.\" @DA_DESTROY -.\" @DA_ENSURE -.\" @DA_SHUNT -.\" @DA_TIDY -.\" @DA_RESET -.\" @DA -.\" @DA_LEN -.\" @DA_SPARE -.\" @DA_OFFSET -.\" @DA_INCLUDE -.\" @DA_EXTEND -.\" @DA_UNSAFE_EXTEND -.\" @DA_SLIDE -.\" @DA_UNSAFE_SLIDE -.\" @DA_SHRINK -.\" @DA_UNSAFE_SHRINK -.\" @DA_UNSLIDE -.\" @DA_UNSAFE_UNSLIDE -.\" @DA_FIRST -.\" @DA_LAST -.\" @DA_PUSH -.\" @DA_POP -.\" @DA_UNSHIFT -.\" @DA_SHIFT -.\" @DAEXC_UFLOW -.\" @DAEXC_OFLOW -.\" @da_ensure -.\" @da_shunt -.\" @da_tidy -.SH "SYNOPSIS" -.nf -.B "#include " - -.BI DA_DECL( type_v ", " type ); -.IB type_v " " a " = DA_INIT;" -.BI "void DA_CREATE(" type_v " *" a ); -.BI "void DA_DESTROY(" type_v " *" a ); - -.BI "void DA_ENSURE(" type_v " *" a ", size_t " n ); -.BI "void DA_SHUNT(" type_v " *" a ", size_t " n ); -.BI "void DA_TIDY(" type_v " *" a ); -.BI "void DA_RESET(" type_v " *" a ); - -.IB type " *DA(" type_v " *" a ); -.BI "size_t DA_LEN(" type_v " *" a ); -.BI "size_t DA_SPARE(" type_v " *" a ); -.BI "size_t DA_OFFSET(" type_v " *" a ); -.BI "void DA_INCLUDE(" type_v " *" a ", size_t " i ); - -.BI "void DA_EXTEND(" type_v " *" a ", long " n ); -.BI "void DA_SHRINK(" type_v " *" a ", long " n ); -.BI "void DA_SLIDE(" type_v " *" a ", long " n ); -.BI "void DA_UNSLIDE(" type_v " *" a ", long " n ); - -.BI "void DA_UNSAFE_EXTEND(" type_v " *" a ", long " n ); -.BI "void DA_UNSAFE_SHRINK(" type_v " *" a ", long " n ); -.BI "void DA_UNSAFE_SLIDE(" type_v " *" a ", long " n ); -.BI "void DA_UNSAFE_UNSLIDE(" type_v " *" a ", long " n ); - -.IB type " DA_FIRST(" type_v " *" a ); -.IB type " DA_LAST(" type_v " *" a ); -.BI "void DA_PUSH(" type_v " *" a ", " type " " x ); -.IB type " DA_POP(" type_v " *" a ); -.BI "void DA_UNSHIFT(" type_v " *" a ", " type " " x ); -.IB type " DA_SHIFT(" type_v " *" a ); - -.BI "void *da_ensure(da_base *" b ", void *" v ", size_t " sz ", size_t " n ); -.BI "void *da_shunt(da_base *" b ", void *" v ", size_t " sz ", size_t " n ); -.BI "void *da_tidy(da_base *" b ", void *" v ", size_t " sz ); -.fi -.SH "DESCRIPTION" -The -.B -header file declares a collection of types, macros and functions which -implement dynamically resizing arrays. -.PP -The macros described here may evaluate their arguments multiple times -unless otherwise specified. -.SS "Creation and destruction" -Each element type must have its own array -type declared using the -.B DA_DECL -macro. Calling -.VS -.BI DA_DECL( type_v ", " type ); -.VE -Declares a new dynamic array type -.I type_v -whose elements have type -.IR type . -.PP -It is conventional to form the name of an array type by appending -.RB ` _v ' -to the base type name. If the base type is a standard type, or is -declared separately from the array, it's also conventional to declare a -macro with the same name as the array type only in uppercase which may -be used to prevent multiple declarations, e.g., -.VS -#ifndef FOO_V -# define FOO_V - DA_DECL(foo_v, foo); -#endif -.VE -The macro -.B DA_INIT -is a valid static initializer for all types of dynamic arrays. For -cases where this isn't appropriate, a dynamic array may be initialized -using the macro -.BR DA_CREATE , -passing it the address of the array. -.PP -Arrays may be disposed of using the -.B DA_DESTROY -macro, which again takes the address of the array. -.SS "Storage allocation" -.PP -Space for new array elements may be reserved using the -.B DA_ENSURE -and -.B DA_SHUNT -macros, which reserve space at the end and beginning of the array -respectively. Both macros take two arguments: the address of an array -object and the number of spare elements required. -.PP -Neither of these macros actually extends the array; both merely allocate -memory for the array to extend itself into. Use the macros -.B DA_EXTEND -and -.B DA_SLIDE -to actually increase the bounds of the array. -.PP -Note that when space is reserved, all the array elements might move. -You should be careful not to depend on the addresses of array elements. -If sufficient storage cannot be allocated, the exception -.B EXC_NOMEM -is thrown (see -.BR exc (3)). -.PP -The macro -.B DA_TIDY -takes one argument: the address of a dynamic array. It minimizes the -amount of memory used by the array. This is a useful function to call -when the array's size has finally settled down. -.PP -The macro -.B DA_RESET -accepts the address of an array. It reduces the length of the array to -zero. No storage is deallocated. Resetting arrays might not be a good -idea if the objects in the array are dynamically allocated. -.SS "Accessing array elements" -If -.I a -is the address of a dynamic array object, then -.BI DA( a ) -is the base address of the actual array. The elements are stored -contiguously starting at this address. An element at index -.I i -may be referenced using the syntax -.BI DA( a )[ i ]\fR. -.PP -The number of elements in the array -.I a -is given by -.BI DA_LEN( a )\fR. -An integer array index -.I i -is -.I valid -if 0 \(<= -.I i -< -.BI DA_LEN( a )\fR. -.PP -There may be some spare slots at the end of the array. In particular, -after a call to -.BI DA_ENSURE( a ", " n ) -there will be at least -.I n -spare slots. The number of spare slots at the end of the array may be -obtained as -.BI DA_SPARE( a )\fR. -.PP -Similarly, there may be spare slots before the start of the array. In -particular, after a call to -.BI DA_SHUNT( a ", " n ) -there will be at least -.I n -spare slots. The number of spare slots before the start of the array -may be obtained as -.BI DA_OFFSET( a )\fR. -.PP -The call -.BI DA_INCLUDE( a ", " i ) -ensures that the array's bounds include the index -.I i -by extending the array if necessary. The exception -.B EXC_NOMEM -is thrown if there isn't enough memory to do this. -.PP -The array's bounds may be extended by -.I n -slots by calling -.BI DA_EXTEND( a ", " n )\fR. -The integer -.I n -must be less than -.BI DA_SPARE( a )\fR; -if this is not the case then the exception -.B DAEXC_OFLOW -is thrown. -Note that -.I n -may be negative to reduce the bounds of the array: in this case it must -be greater than -.BI \-DA_LEN( a ) -or the exception -.B DAEXC_UFLOW -is thrown. The macro -.B DA_UNSAFE_EXTEND -does the same job, but performs no error checking. -.PP -The macro -.BI DA_SLIDE( a ", " n ) -offsets the array elements by -.IR n . -If -.I n -is positive, the array elements are slid upwards, to higher-numbered -indices; if -.I n -is negative, the elements are slid downwards. Precisely, what happens -is that elements which used to have index -.I i -\- -.I n -now have index -.IR i . -The exception -.B DAEXC_OFLOW -is thrown if -.I n -> -.BI DA_OFFSET( a )\fR; -.B DAEXC_UFLOW -is thrown if -.I n -< -.BI \-DA_LEN( a )\fR. -The macro -.B DA_UNSAFE_SLIDE -does the same job, only without the error checking. -.PP -The macros -.B DA_SHRINK -and -.B DA_UNSLIDE -do the same things as -.B DA_EXTEND -and -.B DA_SLIDE -respectively, except that they interpret the sign of their second -arguments in the opposite way. This is useful if the argument is -unsigned (e.g., if it's based on -.BR DA_LEN ). -There are unsafe versions of both these macros too. -.SS "Stack operations" -Dynamic arrays support Perl-like stack operations. Given an array -(pointer) -.I a -and an object of the array's element type -.I x -the following operations are provided: -.TP -.BI DA_PUSH( a ", " x ) -Add -.I x -to the end of the array, increasing the array size by one. -.TP -.IB x " = DA_POP(" a ) -Remove the final element of the array, assigning -.I x -its value and decreasing the array size by one. -.TP -.BI DA_UNSHIFT( a ", " x ) -Insert -.I x -at the beginning of the array, shifting all the elements up one place -and increasing the array size by one. -.TP -.IB x " = DA_SHIFT(" a ) -Remove the first element of the array, assigning -.I x -its value, shifting all the subsequent array items down one place and -decreasing the array size by one. -.PP -The operations -.B DA_PUSH -and -.B DA_UNSHIFT -can fail due to lack of memory, in which case -.B EXC_NOMEM -is thrown. The operations -.B DA_POP -and -.B DA_SHIFT -can fail because the array is empty, in which case -.B DAEXC_UFLOW -is thrown. -.PP -The operations -.B DA_FIRST -and -.B DA_LAST -are lvalues referring to the first and last elements in the array -respectively. They are unsafe if the array is empty. -.SS "Low-level details" -This section describes low-level details of the dynamic array -implementation. You should try to avoid making use of this information -if you can, since the interface may change in later library versions. -In particular, more subtleties may be added which low-level access will -miss. -.PP -Dynamic arrays are structures with the format -.VS -.BI "typedef struct " type_v " {" -.B " da_base b;" -.BI " " type " *v;" -.BI "} " type_v ";" -.VE -The pointer -.B v -indicates the current base of the array. This will move in the -allocated space as a result of -.B DA_SHIFT -and -.B DA_UNSHIFT -(and -.BR DA_SLIDE ) -operations. -.PP -The -.B da_base -structure contains the following elements: -.TP -.B "size_t sz" -The number of allocated slots from -.B v -onwards. -.TP -.B "size_t len" -The number of items considered to be in the array. The allocated space -is usually larger than this. -.TP -.B "size_t off" -The number of allocated slots preceding -.BR v . -The total number of allocated items is therefore -.B sz -+ -.BR off . -.TP -.B "unsigned push" -The number of items pushed or ensured since the last array expansion. -.TP -.B "unsigned unshift" -The number of items unshifted or shunted since the last array expansion. -.PP -The -.B push -and -.B unshift -members are used by the expansion routines to decide how to allocate -free space before and after the array elements following a reallocation. -The other members should be fairly self-explanatory. -.PP -The reallocation routines -.BR da_ensure , -.B da_shunt -and -.B da_tidy -have a regular interface. They're a bit -strange, though, because they have to deal with lots of different types -of arrays. The arguments they take are: -.TP -.BI "da_base *" b -Pointer to the -.B da_base -member of the array block. -.TP -.BI "void *" v -The array base pointer from the array block (i.e., the -.B v -member). -.TP -.BI "size_t " sz -The element size for the array. -.TP -.BI "size_t " n -(For -.B da_ensure -and -.B da_shunt -only.) The number of spare slots required. -.PP -The functions may modify the base structure, and return a newly -allocated (or at least repositioned) array base pointer, or throw -.B EXC_NOMEM -if there's not enough memory. -.PP -The three functions behave as follows: -.TP -.B da_ensure -Ensure that there are at least -.I n -spare slots after the end of the array. -.TP -.B da_shunt -Ensure that there are at least -.I n -spare slots preceding the start of the array. -.TP -.B da_tidy -Reallocate the array to use the smallest amount of memory possible. -.SH "SEE ALSO" -.BR exc (3), -.BR mLib (3). -.SH "AUTHOR" -Mark Wooding,