mpz_t C++ wrapper
modelnine at modelnine.org
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
> 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
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!
More information about the gmp-discuss