# convert

© 2007,2009,2013 John Abbott
GNU Free Documentation License, Version 1.2

- Examples
- User Documentation
  - NumericCast
- Maintenance notes for convert
- Bugs, Shortcomings, etc

CoCoALib Documentation Index

## Examples

- ex-convert1.C

## User Documentation

The header file `convert.H` supplies several conversion functions. They are for converting a numerical value of one type into another numerical type (at least one of the types must be a CoCoALib type). There is also a way of safely converting machine integer values into other integral types.

There are two families of conversion functions:

1. `IsConvertible(dest,src)` the result is a boolean: `true` means the conversion was successful (and the result was placed in `dest`, the 1st arg)
2. `ConvertTo<DestType>(src)` the result is the converted value; if `src` cannot be converted then an error is thrown (with code `ERR::BadConvert`)
3. `ConvertTo<DestType>(src, ErrMesg)` the result is the converted value; if `src` cannot be converted then an error is thrown (with code ErrMesg)

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!!

NOTE 1: Conversion to a `string` can be achieved via `ostringstream`:

        ostringstream buffer;
        buffer << value;
        const string& ConvertedValue = buffer.str();

NOTE 2: Conversion fails if overflow occurs. Currently converting a non-zero `BigRat` to a `double` does not fail if the closest double is 0.

#### NumericCast

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.

## Maintenance notes for convert

The `ConvertTo` fns 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.

## Bugs, Shortcomings, etc

Conversion to C++ integral types other than (unsigned) int/long is not yet supported. Indeed 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 of `BigRat` to `double` ignore underflow, or should it fail?