David M. Warme David at Warme.net
Fri Dec 19 18:34:58 UTC 2014

Proposal: add a new, final int/enum argument to the signature of
each of the memory functions, and have the int/enum value that
GMP passes indicate the type of memory being manipulated.

Some useful attributes to encode in the bits that are passed:

- limb array versus other.

- internal GMP stack temporary versus other.

When re-sizing the limb array for an mpX_t object (where
X \in {z, q, f}), it might also be handy to know the address of the
mpX_t object being re-sized.  Separate re-size function pointers
for each mpX_t type would need only to pass the address of the
mpX_t object, together with the desired new size of the limb array
(plus the int/enum value just described).

Note that re-sizing of mpq_t might be a bit different, since there are
two limb arrays.  Making a custom memory manager that cares too
much about treating mpq_t specially (i.e., as anything other than
two independent mpz_t's) poses risks, because mpq_numref() and
mpq_denref() allow the user to directly manipulate each part as an
independent mpz_t, thereby already losing the information that we are
actually dealing with (the numerator or denominator of) an mpq_t.
The best policy here is probably to simply invoke the "re-size mpz_t"
function separately on the numerator and denominator parts.

This means that you would only need re-size functions for mpz_t and
for mpf_t.

An efficient implementation would be to make these function pointers
default to internal GMP routines that simply "query" as NULL pointers.
With this method, GMP always blindly invokes the pointer, and there
would be no need to test for NULL pointers and explicitly fall back to
the existing mechanism.

David