[Numeric Conversion] numeric_cast and UDTs

From a cursory look through the library doc, it appears that it's possible to create a UDT such that numeric_cast will work with it. For example, class int24 { ... }; // for 24-bit ints; must also specialize // std::numeric_limits, create a range // checking policy, etc. int i; ... int24 myInt = numeric_cast<int24>(i); // throws if i's value won't // fit in an int24 short s = numeric_cast<short>(myInt); // throws if myInt's value won't // fit in a short Can somebody who knows this library please tell me if my understanding is correct -- that numeric_cast can be made to work with integral UDTs? Thanks, Scott

Hi Scott, I'm so sorry for the terrible late response.
From a cursory look through the library doc, it appears that it's possible to create a UDT such that numeric_cast will work with it. For example,
class int24 { ... }; // for 24-bit ints; must also specialize // std::numeric_limits, create a range // checking policy, etc.
int i; ... int24 myInt = numeric_cast<int24>(i); // throws if i's value won't // fit in an int24
short s = numeric_cast<short>(myInt); // throws if myInt's value won't // fit in a short
numeric_cast<> is merly a wrapper around boost::numeric::converter<Target,Source> Converter which instantiates the Converter class with the default policies. The default policy is to use the "internal range checking" logic, which, if the source or target types are UDT, means no range checking at all. But you can, however, create and pass your own range checking policy. Is just that you can't simply use numeric_cast<> then. You need to do it like this: using boost::numeric ; typedef conversion_traits<int,int24> Int24toIntTraits ; typedef converter<int ,int24 ,Int24toIntTraits ,def_overflow_handler ,Trunc<int24> ,raw_converter<Int24toIntTraits> ,YOUR_INT24_TO_INT_RANGE_CHECKER_HERE > Int24toIntConverter ; int24 myInt = Int24toIntConverter::convert(i); And so on for each pair. A little shorter syntax is: int24 myInt = typename make_converter_from<int24 ,def_overflow_handler ,Trunc<int24> ,YOUR_INT24_TO_INT_RANGE_CHECKER_HERE > ::template to<int>::type ::convert(i) ; You can find an example of a custom range checker in the file: libs/numeric/conversion/test/udt_support_test.cpp of the Boost distribution. HTH -- Fernando Cacciola SciSoft http://fcacciola.50webs.com/

"Fernando Cacciola" <fernando_cacciola@hotmail.com> writes:
The default policy is to use the "internal range checking" logic, which, if the source or target types are UDT, means no range checking at all.
But you can, however, create and pass your own range checking policy. Is just that you can't simply use numeric_cast<> then.
That's rather a shame. It would be better for generic code if the checking policy could be specified non-intrusively, e.g. via some traits. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
"Fernando Cacciola" <fernando_cacciola@hotmail.com> writes:
The default policy is to use the "internal range checking" logic, which, if the source or target types are UDT, means no range checking at all.
But you can, however, create and pass your own range checking policy. Is just that you can't simply use numeric_cast<> then.
That's rather a shame. It would be better for generic code if the checking policy could be specified non-intrusively, e.g. via some traits.
I think I agree actually.. The choice of policies vs traits was deliverate, but at this point in time I don't quite remember the rationale. All I recall was a heavy discussion about it. I was already thinking about the possible changes as I wrote this response, and its on my TODO list now. AFAICS, it won't be backward incompatible with the existing numeric_cast<> becasue it will only add range checking iff the user defines the right traits classes. -- Fernando Cacciola SciSoft http://fcacciola.50webs.com/
participants (3)
-
David Abrahams
-
Fernando Cacciola
-
Scott Meyers