.\" @DA_ENSURE
.\" @DA_SHUNT
.\" @DA_TIDY
+.\" @DA_RESET
.\" @DA
.\" @DA_LEN
.\" @DA_SPARE
.\" @DA_UNSAFE_EXTEND
.\" @DA_SLIDE
.\" @DA_UNSAFE_SLIDE
+.\" @DA_SHRINK
+.\" @DA_UNSAFE_SHRINK
+.\" @DA_UNSLIDE
+.\" @DA_UNSAFE_UNSLIDE
.\" @DA_PUSH
.\" @DA_POP
.\" @DA_UNSHIFT
.nf
.B "#include <mLib/darray.h>"
-.BI DA_DECL( atype ", " type );
-.IB atype " " a " = DA_INIT;"
-.BI "void DA_CREATE(" atype " *" a );
-.BI "void DA_DESTROY(" atype " *" a );
+.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(" atype " *" a ", size_t " n );
-.BI "void DA_SHUNT(" atype " *" a ", size_t " n );
-.BI "void DA_TIDY(" atype " *" 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(" atype " *" a );
-.BI "size_t DA_LEN(" atype " *" a );
-.BI "size_t DA_SPARE(" atype " *" a );
-.BI "size_t DA_OFFSET(" atype " *" a );
-.BI "void DA_INCLUDE(" atype " *" a ", size_t " i );
-.BI "void DA_EXTEND(" atype " *" a ", long " n );
-.BI "void DA_UNSAFE_EXTEND(" atype " *" a ", long " n );
-.BI "void DA_SLIDE(" atype " *" a ", long " n );
-.BI "void DA_UNSAFE_SLIDE(" atype " *" a ", long " n );
+.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_PUSH(" atype " *" a ", " type " " x );
-.IB type " DA_POP(" atype " *" a );
-.BI "void DA_UNSHIFT(" atype " *" a ", " type " " x );
-.IB type " DA_SHIFT(" atype " *" a );
+.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 );
+
+.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 );
.B DA_DECL
macro. Calling
.VS
-.BI DA_DECL( atype ", " type );
+.BI DA_DECL( type_v ", " type );
.VE
Declares a new dynamic array type
-.I atype
+.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
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
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)
.PP
Dynamic arrays are structures with the format
.VS
-.BI "typedef struct " atype " {"
+.BI "typedef struct " type_v " {"
.B " da_base b;"
.BI " " type " *v;"
-.BI "} " atype ";"
+.BI "} " type_v ";"
.VE
The pointer
.B v