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 are two families of conversion functions:
IsConvertible(dest,src)
the result is a boolean: true
means the conversion
was successful (and the result was placed in dest
, the 1st arg)
ConvertTo<DestType>(src)
the result is the converted value; if src
cannot
be converted then an error is thrown (with code ERR::BadConvert
)
The IsConvertible
functions attempt to convert the value to the
type of the first arg; if the attempt succeeds, the converted value is
assigned to the first arg and true
is returned, otherwise
false
is returned (the value of the first arg is unchanged).
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 |
|
long | RingElem |
equiv to IsInteger & range check |
BigInt |
RingElem |
same as IsInteger |
BigRat |
RingElem |
same as IsRational |
long | double | value must be integral & in range |
BigInt |
double | |
BigRat |
double | |
double | BigInt |
may have rounding error! |
double | BigRat |
may have rounding error! |
Conversion to a double
fails if overflow occurs. In contrast,
underflow does not cause failure, and the converted value is simply 0.
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. A
similar comment applies to the impl of ConvertTo
; note that when calling
a ConvertTo
fn, it is necessary to specify only the first template type
parameter (the compiler guesses the second parameter).
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.
The IsConvertible
functions are a hotch potch, but how can it be done better?
BOOST has numeric_cast
which is like NumericCast
for built in numerical types.
Sooner or later we should use that.
Should conversion to double
ignore underflow, or should it say that
the conversion failed?