The header file convert.H
supplies several conversion functions and
procedures. These functions/procedures are for converting a value of one
type into another type (at least one of the types must be a CoCoALib type);
the conversion may fail -- failure is reported in different ways by
different functions. There is also a way of safely converting machine
integer values into other integral types.
There is one family of conversion functions: it is called
IsConvertible
(see Bugs section below for the function ConvertTo
).
There is also a family of procedures: these are called convert
.
The IsConvertible
functions attempt to assign the value of the second
argument to the first argument; if the attempt succeeds, they return
true
, otherwise they return false
-- the value of the first argument
may be modified even when false
is returned. The procedures convert
are very similar to the functions IsConvertible
except that no value
is returned, and if the conversion fails then an ERR::BadConvert
is
thrown.
Here is a summary of the conversions currently offered:
"to" type | "from" type | notes |
---|---|---|
(unsigned) long | BigInt |
|
(unsigned) int | BigInt |
|
(unsigned) long | BigRat |
|
(unsigned) int | BigRat |
|
string | BigInt |
opt. 3rd arg is base (2--36) |
string | BigRat |
opt. 3rd arg is base (2--36) |
BigInt |
string | opt. 3rd arg is base (2--36) |
BigRat |
string | opt. 3rd arg is base (2--36) |
BigInt |
double | |
BigRat |
double | |
double | BigInt |
|
double | BigRat |
Conversion from BigInt
to string
may return false (e.g. if memory is insufficient).
Conversions to and from string
accept a third argument
indicating the base (between 2 and 36). By default the base 10 is used.
As a special case, base
may also be zero the chooses the standard C
convention for specifying the base (8/10/16): viz. if the string
starts "0x" (or "0X") then base
=16, otherwise if the string starts
with "0" then base
=8, otherwise base
=10.
Specifying a base outside the permitted range will throw ERR::BadNumBase
.
Conversion to a double
fails if overflow occurs. In contrast,
underflow does not cause failure, and the converted value is simply zero.
There is a templated class called NumericCast
; it is roughly analogous
to BOOST::numeric_cast
, and will eventually be replaced by direct use
of this BOOST feature. It is to be used for converting safely from one
machine integer type to another: the conversion succeeds only if the value
supplied can be represented by the destination type. In case of failure an
ERR::BadConvert
exception is thrown.
The convert
procedures simply call the corresponding IsConvertible
function -- indeed a template implementation is appropriate here.
Only some combinations of IsConvertible
functions are present so far.
The class NumericCast
has a single template argument, and the constructor
has a separate template argument to allow the "natural syntax" like that of
static_cast
(or BOOST's numeric_cast
). I used a class rather than a templated function because a
function would have required the user to specify two template arguments
(i.e. unnatural syntax). I don't know if this is the best way to achieve
what I want, but it is simple enough that there are obviously no deficiencies.
Getting an exception clean implementation for the conversion of a BigInt
to a
string
was not entirely simple, but I do not see how to do it better given
the interfaces to GMP and string
.
The IsConvertible
functions are a hotch potch, but how can it be done better?
Is the C convention for specifying the base when converting from a string useful here? JAA cannot see when it would ever really be used.
The implementation of convert(string&, const BigInt&)
is not very efficient
(neither in terms of speed nor in terms of space used).
BOOST has numeric_cast
which is like NumericCast
for built in numerical types.
Sooner or later we should use that.
There is a commented out template conversion operator called ConvertTo
.
Is this sort of conversion function useful for anyone??? -- perhaps for
the pseudo ctors of SmallFpImpl
CheckCtorArg(ConvertTo<long>(P)).
Does operator ToType
for ConvertTo
make a useless copy?
Old documentation
The ConvertTo
functions attempt to convert the given value into the
type specified by the template argument. The value returned is the converted
value; an ERR::BadConvert
exception is thrown if the conversion fails.
Should conversion to double
ignore underflow, or should it say that
the conversion failed?