Features

Copy construction is disabled by default (for now) to prevent inadvertent
copying. Instead use f(move(z)) or f(z.move) (from std.algorithm.mutation)
to pass by move or f(z.dup) to pass by value (via .dup member function).

If you really need to have copy construction you can use CopyableMpZ.

Implementation is optimized through

mapping of GMP's C macros into D inline functions that operate directly on the
internal C-representations __mpz_struct and __mpq_struct,

passing of MpZ-typed parameters as auto ref const in combination with
conditional compilation for r-value MpZ passed parameters via
__traits(isRef). This enables clever reuse of mpz_t instances when passed
to __gmpz-functions. For instance, x + 42.Z can be lowered to

__gmpz_add(rhs._ptr, this._ptr, rhs._ptr);
return move(rhs);

in

opBinary!"+"()(auto ref const MpZ rhs)

Compilation Performance

Compilation is very fast; DMD compiles gmp-d in 0.04 seconds on my machine and
test-build in 0.22 seconds.

Run-time Performance

Wrapper is as light-weight as possible; Some D-functions directly access the
internal C-datastructure exposed by the structs and macros in the C-headers of
GNU GMP.

Limitations

Note that D's __traits(isRef) currently cannot be used to distinguish l-value
from r-value passing of this. This severly limits the possibilities of using
C++-style expression
templates to realize lazy
evaluation in operator overloading. If this limitation were to be fixed
(probably via some introspection mechanism other than the trait isRef or
non-struct-member operator overloading), this library could implement lowering
of expressions such

Z result = base^^exp % modulo

to the builtin

__gmpz_powm(result._ptr, base._ptr, expr._ptr, modulo._ptr)

See the unittests for MpzAddExpr, MpzMulExpr, etc for details on how this
currently can be implemented and verified (in ccc-version) with free
functions such add and sub.

Future

There are more mpz_t- and mpq_t-functions that should be wrapped but these are good start.