|
Boost Numeric Conversion LibraryType Requirements
|
---|
Both arithmetic (built-in) and user-defined numeric types require proper specialization of
std::numeric_limits<>
(that is, with (in-class) integral constants).
The library uses std::numeric_limits<T>::is_specialized
to detect whether
the type is builtin or user defined, and std::numeric_limits<T>::is_integer,
std::numeric_limits<T>::is_signed
to detect whether the type is integer or floating point; and whether it is signed/unsigned.
The default Float2IntRounder policies uses unqualified calls to functions floor()
and ceil()
; but the standard functions are introduced in scope by a
using directive:
using std::floor ; return floor(s);
Therefore, for builtin arithmetic types, the std functions will be used. User defined types should provide overloaded versions of these functions in order to use the default rounder policies. If these overloads are defined within a user namespace argument dependent lookup (ADL) should find them, but if your compiler has a weak ADL you might need to put these functions some place else or write your own rounder policy.
The default Trunc<> rounder policy needs to determine if the source value
is positive or not, and for this it evaluates the expression "s < static_cast<S>(0)".
Therefore, user defined types require a visible operator < in order to use
the Trunc<> policy (the default).
Conversion Traits
If a User Defined Type is involved in a conversion, it is assumed that
the UDT has wider range than any built-in
type, and consequently the values of some converter_traits<>
members are hardwired regardless of the reality. The following table summarizes
this:
subranged=false
supertype=Target
subtype=Source
subranged=true
supertype=Source
subtype=Target
subranged=false
supertype=Target
subtype=Source
The Traits member udt_mixture
can be used to detect whether a
UDT is involved and to infer the validity of the other members as shown above.
Range Checking
Because User Defined Numeric Types might have peculiar ranges (such as an unbounded
range), this library does not attempt to supply a meaningful range checking
logic when UDTs are involved in a conversion. Therefore, if either Target or
Source are not built-in types, the bundled range checking of the converter<>
function object is automatically disabled. However, it is possible to supply
a user-defined range-checker. See Special Policies
There are two components of the converter<>
class that might
require special behavior if User Defined Numeric Types are involved: the Range
Checking and the Raw Conversion.
When both Target and Source are built-in types, the converter class uses an
internal range checking logic which is optimized and customized for the
combined properties of the types.
However, this internal logic is disabled when either type is User Defined. In
this case, the user can specify an external range checking policy which
will be used in place of the internal code.
See UserRangeChecker policy for details.
The converter class performs the actual conversion using a Raw Converter policy.
The default raw converter simply performs a "static_cast<Target>(source)".
However, if the a UDT is involved, the static_cast might not work. In this case,
the user can implement and pass a different raw converter policy.
See RawConverter policy for details
Back to Numeric Conversion library index
Revised 23 June 2004
© Copyright Fernando Luis Cacciola Carballal, 2004
Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)