
Alastair Reid wrote:
Interfaces to other things with alignment constraints (e.g., memory allocators) often have one of two generalizations:
1) (Most likely to be useful):
--| flushBytes h n aligns the strean to the next 2^n byte (bit?) boundary flushBytes :: BinHandle -> Int -> IO ()
2) (Less likely to be useful in this context)
--| flushBytes h m n aligns the stream such that the position p satisfies: -- p `mod` 2^m == n flushBytes :: BinHandle -> Int -> IO ()
Years (decades?) ago it occurred to me that the above two options for expressing alignment could neatly (at least in terms of the interface) be coalesced, as follows. An alignment constraint for allocation in a memory area is expressed as an unsigned integer of the same size as addresses for that memory area. An alignment constraint of zero is not sensible. (It could be used to indicate a default value or could evoke an error, depending on the application.) The alignment constraint encodes the values `m` and `n` from the second alternative above as `2^m + n`. Operationally, the combined alignment constraint is split at the uppermost "1" bit, with that bit's position indicating the power of two and the lower bits indicating the desired remainder upon division by that power of two. This scheme compactly encodes all meaningful pairs of values of `m` and `n` and has only a single inherently meaningless combined value--the aforementioned value zero. I've never had the opportunity to use or implement such an interface, but I have occasionally missed the generality it provides when I had to allocate extra space in order to place a descriptor immediately before a well-aligned bunch of bits. Has anyone seen such an interface? -- Dean