mpz_t C++ wrapper

Heiko Wundram modelnine at
Thu May 1 23:39:10 CEST 2008

Am Donnerstag, 1. Mai 2008 14:08:00 schrieb Torbjorn Granlund:
> Heiko Wundram:
>   I know that mpz_class allows you to use the underlying mpz functions
>   directly, thus optimizing the temporary usage explicitly, but
>   especially with the ability to overload operators, I find this to be
>   quite cumbersome to read in the end (and not very C++-like), and
>   additionally this also generates convoluted code, because mpz_class
>   does not override operator mpz_srcptr or mpz_ptr (requiring you to
>   access the mpz_t pointer with get_mpz_t()), which is somewhat of a
>   PITA.
> mpz_ptr and mpz_srcptr are internal types, and therefore no
> user-visible interfaces should be made to them.

As quite a lot of functionality which operate on mpz_t's isn't available 
directly in a class/operator encapsulated interface (think of mpz_powm_*, 
which I use extensively in my ElGamal implementation), I really found it a 
PITA to always have to type get_mpz_t() for each call to a base mpz_* 
function, as it (IMNSHO) unnecessarily makes the code more verbose.

This was basically the first reason for me to reimplement mpz_class, and as I 
found that it was nigh impossible to do away with the need to call 
get_mpz_t() in the current framework (simply because expression classes and 
the actual mpz_t carrying wrapper objects are both instances of the same 
template class), I decided to go a different route and separate expression 
objects from the actual class carrying an mpz_t itself, so that they share no 
inheritance relationship whatsoever.

The class carrying an mpz_t (BigInteger) is basically just a shim for the 
mpz_t object. That's why casting it to an mpz_srcptr or mpz_ptr is explicitly 
allowed (because that's all it is), and this is also used extensively in the 
actual arithmetic framework, which implements an operation as a set of 
overloaded functions on mpz_[src]ptrs and other data types and which happen 
to possibly get passed a BigInteger reference (which is implicitly casted to 
the required pointer type) by the operator implementation.

The operator implementation itself does use the distinction between an mpz_ptr 
and a BigInteger&, whereas the former is used to signal a destination that 
might possibly be referenced in the expresion tree (so, its value cannot be 
changed/updated during the evaluation of the tree), and the latter is used 
when it is sure that the object is a true "temporary," created by the 
operator evaluation system, and as such can be updated by an expression (as 
there are no other references to it in the expression tree).

> Heiko Wundram:
>   I plan on releasing the code under a BSD-style license anyway,
>   it's just that
> Joerg Arndt:
>   At least release it also under LGPL, else the code is unlikely to
>   be ever part of GMP!  TG might have more comments here...
> Furthermore, code for GMP inclusion needs to be assigned to the FSF.

Clear, and that shouldn't be a problem.

> Heiko Wundram:
>   currently (because I only use _very_ limited parts of the wrapper
>   in my application) it's probably broken in one aspect or another,
>   and generally I can't actually say that there is any speed
>   improvement in a "real-world" application of it (simply because I
>   don't know what "real-world" terms look like). It shouldn't
>   perform worse than mpz_class, anyway (except possibly at
>   compilation speed), but I just want to escape all the NIH callers
>   before releasing it... :-)

Just to make this clear: the operator evaluation framework _should_ not have 
any bugs as it stands (and does not rely on any compiler-specific behaviour, 
except for the postfix increment and decrement operators, which work, but 
generate a warning on g++, for example, see the source for why); the only 
thing where bugs might have crept in is in the implementation of the specific 
operations (i.e., the set of functions in the namespaces 

> Joerg Arndt:
>   Even if incomplete put it online (with a comment about the status).
>   People may well contribute if the thing is promising.
>   Hopefully TG comments some more, especially on what the priorities
>   to have a quality C++ wrapper are.
> Improvements to the C++ wrapper would be welcome.  Unfortunately, my
> C++ knowledge is limited, so I cannot make any quality assessments of
> various approaches.
> It would be better to improve the existing wrapper, then throw it away
> and replace it.  Only if there is agreement among C++ experts that a
> completely different approach is needed, a rewrite should be
> considered.

See my reasoning above, why I took a different route (i.e., the two wrappers 
are actually conceptually different), and why I didn't spend the time trying 
to improve the current wrapper.

As the two basic types (i.e., integers and expressions) are separate, this 
leads to quite a bit of macro-(ab)use in the header file, because lots of 
repetitive boiler-plate code has to be created to implement the operators, 
which the current gmpxx.h doesn't need to do so extensively. Finally, this is 
just an mpz_t wrapper, so it doesn't replace gmpxx.h, it complements it 
specifically for mpz_t objects.

Thanks for taking the time to reply!

Heiko Wundram

More information about the gmp-discuss mailing list