[integer] Request: long long (64 bits) support for int_t and uint_t
I would like to have "long long" and "unsigned long long" supported by boost::int_t and boost::uint_t. E.g., on Win32, VC++, I would expect int_t<64>::least to get me a long long. Are there plans to add this kind of support? Otherwise, should I submit my request as a ticket to svn.boost.org/trac/boost ? It looks like "long long" support can be added quite easily, as I already did so on my local copy of boost/integer.hpp. -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center
Hi,
1. With most (all?) 64-bit Linux/Unix following the LP64 model:
http://www.unix.org/version2/whatsnew/lp64_wp.html
int_t<64>::least could give either a "long" or "long long" .
uint_t<64>::least could give either a "unsigned long" or "unsigned long
long".
In this case I'd prefer just "long" or "unsigned long".
2. However with M$ 64bit Windows following the ILP64 there is no other
choice but int_t<64>::least gives "long" or "long long".
However even on 64-bit Windows with Interix (SUA/SFU) the LP64 model is
is followed.
3. Now I remember someone already already come up with a patch?
Thanks
Shams
--
"Niels Dekker - mail address until 2007-11-30"
I would like to have "long long" and "unsigned long long" supported by boost::int_t and boost::uint_t. E.g., on Win32, VC++, I would expect int_t<64>::least to get me a long long.
Are there plans to add this kind of support? Otherwise, should I submit my request as a ticket to svn.boost.org/trac/boost ?
It looks like "long long" support can be added quite easily, as I already did so on my local copy of boost/integer.hpp.
-- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center
Shams wrote:
1. With most (all?) 64-bit Linux/Unix following the LP64 model: http://www.unix.org/version2/whatsnew/lp64_wp.html
int_t<64>::least could give either a "long" or "long long" . uint_t<64>::least could give either a "unsigned long" or "unsigned long long".
In this case I'd prefer just "long" or "unsigned long".
No problem, I guess. I guess that after adding long-long-support, int_t<64>::least would still select "long", rather than "long long", on a platform that has 64-bits "long" integers.
2. However with M$ 64bit Windows following the ILP64 there is no other choice but int_t<64>::least gives "long" or "long long".
Hmmm... I wasn't even aware of ILP64! Thanks! Does Boost support ILP64 platforms? If so, I guess int_t<32>::least should select _int32, instead of int, on such a platform!
3. Now I remember someone already already come up with a patch?
Apparently yes! Just after posting my question, I found a ticket, submitted by "me22" a year ago, and assigned to Daryle Walker: Ticket #653, "[integer] add support for integers longer than long" http://svn.boost.org/trac/boost/ticket/653 When would it be implemented within a Boost release version? Kind regards, Niels
On 03/06/07, Niels Dekker - mail address until 2007-11-30 wrote:
Shams wrote:
1. With most (all?) 64-bit Linux/Unix following the LP64 model: http://www.unix.org/version2/whatsnew/lp64_wp.html
int_t<64>::least could give either a "long" or "long long" . uint_t<64>::least could give either a "unsigned long" or "unsigned long long".
In this case I'd prefer just "long" or "unsigned long".
No problem, I guess. I guess that after adding long-long-support, int_t<64>::least would still select "long", rather than "long long", on a platform that has 64-bits "long" integers.
The current implementation method will give the potentially smaller of the 2 types, so int_t<64>::least would give long if longs and long longs are both 64-bits, just as it currently gives int for int_t<32>::least when long and int are both 32-bits. The implementation is quite ingenious, actually. On a proverbial toaster with 42-bit everything, a request for int_t<39>::least would give a signed char, the "smallest" type.
2. However with M$ 64bit Windows following the ILP64 there is no other choice but int_t<64>::least gives "long" or "long long".
Hmmm... I wasn't even aware of ILP64! Thanks! Does Boost support ILP64 platforms? If so, I guess int_t<32>::least should select _int32, instead of int, on such a platform!
The current implementation deals only in standard C++98 types. Unfortunately, __int32 wouldn't fit in perfectly. int could plausibly be 16 or 64 bits, so there's no way of knowing where in the ordering to put it. Of course, some (rather reasonable) assumptions could be make about platforms that do provide it.
3. Now I remember someone already already come up with a patch?
Apparently yes! Just after posting my question, I found a ticket, submitted by "me22" a year ago, and assigned to Daryle Walker: Ticket #653, "[integer] add support for integers longer than long" http://svn.boost.org/trac/boost/ticket/653
Apparently not everything got transitioned over to trac perfectly. On SF it told you what this mysterious "me22"'s name was. You can still find the patch in the mailing list archives: http://lists.boost.org/Archives/boost/2006/06/106262.php Or, if you're a boost admin, at http://sourceforge.net/tracker/index.php?func=detail&aid=1507034&group_id=7586&atid=307586 There was someone else who also offered a similar patch a few months back.
When would it be implemented within a Boost release version?
Hopefully soon :) My patch is nearing a year old, but with 1.34 out the door and the current push for more frequent releases, soon is plausible. ~ Scott McMurray
Hi me22!!! :-) Scott McMurray (aka me22) wrote about boost::int_t<Bits>:
The implementation is quite ingenious, actually. On a proverbial toaster with 42-bit everything, a request for int_t<39>::least would give a signed char, the "smallest" type.
I agree about it being quite ingenious. And I like the fact that it supports 42-bit-everything-systems. But still, personally I'd rather have it support all kinds of 64-bits platforms...
Does Boost support ILP64 platforms? If so, I guess int_t<32>::least should select _int32, instead of int, on such a platform!
The current implementation deals only in standard C++98 types.
And should it stay that way?
Now I remember someone already already come up with a patch?
You can still find the patch in the mailing list archives: http://lists.boost.org/Archives/boost/2006/06/106262.php
I like your int_exact_t<Bits>::exact, Scott! It could really be of
help, for my own Boost-based project. Still I don't like the fact that
it will fail to get me a 32-bits integer (_int32) on an ILP64 platform.
Why not having int_exact_t entirely based on the exact-width integer
types from
Oops, a significant typo! I just wrote:
Why not having int_exact_t entirely based on the exact-width integer types from
? [ <---- typo!!! ]
But I meant to ask:
Why not having int_exact_t entirely based on the exact-width integer
types from
On 05/06/07, Niels Dekker wrote:
I agree about it being quite ingenious. And I like the fact that it supports 42-bit-everything-systems. But still, personally I'd rather have it support all kinds of 64-bits platforms...
The current implementation deals only in standard C++98 types.
And should it stay that way?
My proposed patch doesn't, which suggests my answer.
I like your int_exact_t<Bits>::exact, Scott! It could really be of help, for my own Boost-based project. Still I don't like the fact that it will fail to get me a 32-bits integer (_int32) on an ILP64 platform.
Why not having int_exact_t entirely based on the exact-width integer types from
?
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. Note the #error defaults not correct; you must
hand modify boost/cstdint.hpp. This is important for people using
boost on toasters with 11-bit bytes :P
For obvious reasons, the implementation cannot just blindly add
specializations for int_t
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.)
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. How does the signed and unsigned types together help you? My concern was simply to add support without changing semantics, so I haven't looked at interface one way or the other. 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). 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. (I suppose a debate could be held on whether that's a positive or a negative. I suppose the void does fit well with the "it's only an error if you try to use it" idea that comes up a few times in D&E, but that's a language-level idea that's rather counter to the application-level idea that's rather opposed to failing early and fast...)
AFAIK, such a template would correctly support any 64-bits platform, including ILP64. What do you think?
It would certainly support all the desktops and servers I know of. The question is how well it deals with embedded stuff and toasters. Of course, I have no idea where (whether?) anyone uses boost/integer.hpp... ~ Scott McMurray
I have been using both Boost lib and GameDev SDL lib in same projects. Both of the lib have very good platform independency. But they have some functionalities overlapping each other and I would like to use only one of them. The timer lib in GameDev SDL is very easy to use and I hope such lib or functionally similar one exists in Boost lib. I had a look at boost archive on previous discussion on implementing Boost timers and feel that there is still no good implementation of timer in Boost lib (correct me if I am wrong). Anybody in this email list had a look at GameDev timer and have considered implementing such a lib in Boost? Best regards, Fanz =================================== Goldiom Systems LLC - Information and Communication Technology Provider Email: fanzhe.cui@goldiom.com Tel: 973-210-4254 www.goldiom.com
Why not having int_exact_t entirely based on the exact-width integer types from
?
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.
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.
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
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
On 06/06/07, Niels Dekker wrote:
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 how well C99 has spread, I'd be worried about assuming too much quick penetration for C++09. 9-bit bytes are still allowed by C++, if not POSIX, and just using 8/16/32/64 doesn't get us any other things that might be available. Of course, I doubt anyone actually uses boost on such machines anyways...
Given the fact that
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.
Agreed.
I'm wondering about a special thing like this:
template
I think this is not a problem.
requires template specialization as well.
Right, of course. I thought too hard about one bit and forgot the other half :| Suppose that we just went and used the cstdint.hpp method. Would we then just using uint_t<N> = uint_exact_t< ((N-1)|7)+1 >; Since all the types we know about would be multiples of 8 bits?
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
::signed_type> my_types; Then I would use both my_types::signed_type and my_types::unsigned_type.
On the other hand, I suppose there might be value in making them meta-functions, with just ::type (and maybe ::fast). int_fast_t should probably also get a ::type, for metafunction usage. (Though I'm by no means a qualified enough MPL wizard to know whether this would be at all useful.) Another option would be to go for stdint-style naming, and make int_t<N>::type be the exact type, and add new int_least_t and int_fast_t metafunctions. And with C++09, you have using my_types<T> = int_exact_t<32,T>; // or whatever the syntax is then my_type<signed>::type and my_type<unsigned>::type, so you can get away without multiple typedefs in the same struct. BTW: CHAR_BIT or integer_traits<unsigned char>::digits, not 8 :P
BTW, a struct like get_unsigned<Integer> would be helpful to me as well. Boost has such a struct implemented twice: in both
and . But unfortunately neither of them supports long long. Also they both seem to be an undocumented implementation detail.
I went looking for a boost answer to
That's a good question! How many users would be affected by a drastic change of
? And would the changes we're discussing increase the popularity of ?
And noticed a number of things like:
/usr/include/boost/xpressive/traits/cpp_regex_traits.hpp has
"define an unsigned integral typedef of the same size as std::ctype_base::mask"
So this does seem like a good suggestion.
Easy to implement, too:
template <typename T>
struct unsigned_ {
BOOST_STATIC_ASSERT(integer_traits<T>::is_specialized);
// and maybe BOOST_STATIC_ASSERT(integer_traits<T>::is_signed);
typedef uint_exact_t
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. :-)
Having adjectives as types is fun, occasionally. The wonders of partial specialization :)
FWIW, I find it acceptable to have int_t<31>::exact giving "void".
I agree. ~ Scott McMurray
Scott McMurray (me22) wrote:
Given the fact that
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. Agreed.
Thanks :-)
I suppose there might be value in making them meta-functions, with just ::type
Okay, so instead we could have a templated struct int_exact<Bits>,
containing just one type, taken from
I'm wondering about a special thing like this: template
struct stdint_t { typedef U type; } template <typename U = void> struct stdint_t<32,U> { typedef int32_t type; } // and etc
Not completely clear to me...
Suppose that we just went and used the cstdint.hpp method. Would we then just using uint_t<N> = uint_exact_t< ((N-1)|7)+1 >; Since all the types we know about would be multiples of 8 bits?
Hmmm... I don't really understand this formula either: (((N-1)|7)+1)
int_exact
BTW: CHAR_BIT or integer_traits<unsigned char>::digits, not 8 :P
Oops! You're absolutely right! I was very very bad ;-)
/usr/include/boost/xpressive/traits/cpp_regex_traits.hpp has "define an unsigned integral typedef of the same size as std::ctype_base::mask" So this does seem like a good suggestion.
Easy to implement, too: template <typename T> struct unsigned_ { BOOST_STATIC_ASSERT(integer_traits<T>::is_specialized); // and maybe BOOST_STATIC_ASSERT(integer_traits<T>::is_signed); typedef uint_exact_t
::type type; }; template <typename T> unsigned_<T> make_unsigned(T x) { return unsigned_<T>(x); }
I'm afraid I will lose the value of my argument (x), when passing it to make_unsigned, because it returns a struct that doesn't have any data! But at least it will get me the right unsigned type :-)
Or maybe a new metafunction, int_size_as<T> = int_exact_t
;
That's possible... BTW, I think we might drop the "_t", and call the struct "int_exact", instead of "int_exact_t", when the typedef is simply called "type". Because IMO int_exact<32>::type is clear enough. :-) So... any suggestions on how to get those simple structs like int_exact and uint_exact into the Boost Integer Library? Kind regards, Niels
Shams wrote:
1. With most (all?) 64-bit Linux/Unix following the LP64 model: http://www.unix.org/version2/whatsnew/lp64_wp.html
2. However with M$ 64bit Windows following the ILP64 there is no other choice but int_t<64>::least gives "long" or "long long".
Are you sure you meant to type "ILP64"? If I understand the above document correctly, Microsoft chose the LLP64 model. Under Windows 64, int and long are both 32 bits, while long long and pointer are 64 bits. int_t<64>::least would need to give "long long" or "__int64" under 64-bit Windows. Microsoft seems to prefer __int64 in their documentation and system headers.
Yes you're right, I meant LLP64.
At least they've gone with LP64 on Interix (SUA) or forced to I should say.
Thanks
Shams
--
"Andrew Holden"
Shams wrote:
1. With most (all?) 64-bit Linux/Unix following the LP64 model: http://www.unix.org/version2/whatsnew/lp64_wp.html
2. However with M$ 64bit Windows following the ILP64 there is no other choice but int_t<64>::least gives "long" or "long long".
Are you sure you meant to type "ILP64"? If I understand the above document correctly, Microsoft chose the LLP64 model. Under Windows 64, int and long are both 32 bits, while long long and pointer are 64 bits. int_t<64>::least would need to give "long long" or "__int64" under 64-bit Windows. Microsoft seems to prefer __int64 in their documentation and system headers.
participants (5)
-
Andrew Holden
-
fanzhe cui
-
me22
-
Niels Dekker - mail address until 2007-11-30
-
Shams