
Why not having int_exact_t entirely based on the exact-width integer types from <boost/cstdint.hpp>?
me22 wrote:
The current implementation works in an entirely standard manner, which I consider an advantage.
cstdint.hpp, on the other hand, consists solely of by-hand listings of using declarations and typedefs that require manual configuration work for new platforms.
<stdint.h> is part of the C Standard already, and <cstdint> will be part of C++09. So I don't expect to have much manual configuration work for new platforms... Do you? Given the fact that <cstdint.hpp> is part of Boost already, it would make sense to me to allow easy access to its integer types by means of a templated struct like int_exact.
Actually I was thinking of a far more simple implementation, as follows. (In practice, I find it quite convenient to have the signed and the unsigned type grouped within one struct.)
//////////////////////////////////////////////////////////// template <unsigned Bits> struct int_exact { }; ... template <> struct int_exact<32> { typedef int32_t signed_type; typedef uint32_t unsigned_type; };
#ifndef BOOST_NO_INT64_T template <> struct int_exact<64> { typedef int64_t signed_type; typedef uint64_t unsigned_type; }; #endif ////////////////////////////////////////////////////////////
I'm not sure if that is actually simpler, as it requires template specialization, which has historically been avoided where possible, for compatibility. I think the problem platforms are being dropped in 1.35, however, so this may no longer be a problem.
I think this is not a problem. <boost/integer.hpp> requires template specialization as well. But it surely isn't as simple as my struct :-)
How does the signed and unsigned types together help you?
I need to have signed and unsigned types of the same particular size. So I would like to do something like this: typedef typename int_exact<sizeof(T)*8>::signed_type> my_types; Then I would use both my_types::signed_type and my_types::unsigned_type. BTW, a struct like get_unsigned<Integer> would be helpful to me as well. Boost has such a struct implemented twice: in both <typeof/int_encoding.hpp> and <wave/util/flex_string.hpp>. But unfortunately neither of them supports long long. Also they both seem to be an undocumented implementation detail.
If we're going all-out on interface, allowing specializations and stuff, there are a number of other possibilities. One fun one that's even backwards compatible is still allowing int_t<25>::least and uint_t<25>::least, but also int_t<25,unsigned>::least (and int_t<32,signed>::least).
It would be very nice to allow specifying signed/unsigned as a parameter argument indeed! Specifying a 32-bits unsigned integer by int_t<32, unsigned>::exact, and a 64-bits signed integer by int_t<64, signed>::exact. :-)
The reason I didn't consolidate ::exact into int_t and uint_t originally was that it makes it annoying (or maybe impossible) to preserve the non-existence semantics for the ::exact typedef when such a type is unavailable. Making it give void is easy and does almost all the same things, but then you don't get an error from typedef int_t<31>::exact myint; at typedef definition, only when the typedef is actually used.
FWIW, I find it acceptable to have int_t<31>::exact giving "void".
Of course, I have no idea where (whether?) anyone uses boost/integer.hpp...
That's a good question! How many users would be affected by a drastic change of <boost/integer.hpp>? And would the changes we're discussing increase the popularity of <boost/integer.hpp>? Kind regards, -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center