Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Portable list of unsigned integer types

Reply
Thread Tools

Portable list of unsigned integer types

 
 
Fred Zwarts
Guest
Posts: n/a
 
      10-13-2009
I have created a template function for a generic algorithm.
For unsigned integer types, a small modification in the algorithm is needed,
because I can't use negative values there.
So, I want to make specializations for all unsigned integer types.
I assume that it is not possible in C++ to write one specialization for all
unsigned integer type, but that a specialization for each unsigned integer type
must be created.
Since this software runs on different platforms, I wonder whether it is
possible to write a complete set of specializations in a platform independent way.

I first tried to write specializations for uint8_t, uint16_t, uint32_t and uint64_t
as defined in inttypes.h, but it turns out that on some platforms some
unsigned integer types are still missing. (Under Windows e.g.,
there is more than one 32-bit unsigned integer type.)
Types like size_t and clock_t map to different types on different platforms.
I wonder whether it is possible to create a complete list,
without using conditional code selection in the preprocessor.
Is the list "unsigned char, unsigned short, unsigned int, unsigned long and unsigned long long"
complete and without overlap (as far as specializations concern) for all platforms?
Should I add unsigned wchar_t, or is it covered already?

(I know that char needs special attention. I know how to handle that case.)
 
Reply With Quote
 
 
 
 
Francesco S. Carta
Guest
Posts: n/a
 
      10-13-2009
"Fred Zwarts" <F.Zwa...@KVI.nl> wrote:
> I have created a template function for a generic algorithm.
> For unsigned integer types, a small modification in the algorithm is needed,
> because I can't use negative values there.
> So, I want to make specializations for all unsigned integer types.
> I assume that it is not possible in C++ to write one specialization for all
> unsigned integer type, but that a specialization for each unsigned integer type
> must be created.
> Since this software runs on different platforms, I wonder whether it is
> possible to write a complete set of specializations in a platform independent way.
>
> I first tried to write specializations for uint8_t, uint16_t, uint32_t and uint64_t
> as defined in inttypes.h, but it turns out that on some platforms some
> unsigned integer types are still missing. (Under Windows e.g.,
> there is more than one 32-bit unsigned integer type.)
> Types like size_t and clock_t map to different types on different platforms.
> I wonder whether it is possible to create a complete list,
> without using conditional code selection in the preprocessor.
> Is the list "unsigned char, unsigned short, unsigned int, unsigned long and unsigned long long"
> complete and without overlap (as far as specializations concern) for all platforms?
> Should I add unsigned wchar_t, or is it covered already?
>
> (I know that char needs special attention. I know how to handle that case.)


Your list seems exhaustive, and "unsigned wchar_t" should be already
covered by your list (after all, it should be just an unsigned integer
somewhat bigger than char). But you'll eventually get more certain
answers about this.

About avoiding to create all those specializations, can you get along
with duplicating the body of your template to include both algorithms,
checking then for unsigned-ness at runtime via numeric_limits?

The compiler could then optimize away the algorithm version that
doesn't happen to be appropriate for each type - at least, I suppose
so, I'd have to check if it works but I'm not so sure I will able to.

Just an idea off the top of my head.

--
Francesco S. Carta, http://fscode.altervista.org
 
Reply With Quote
 
 
 
 
Francesco S. Carta
Guest
Posts: n/a
 
      10-13-2009
On 13 Ott, 12:45, "Francesco S. Carta" <entul...@gmail.com> wrote:
> "Fred Zwarts" <F.Zwa...@KVI.nl> wrote:
> > I have created a template function for a generic algorithm.
> > For unsigned integer types, a small modification in the algorithm is needed,
> > because I can't use negative values there.
> > So, I want to make specializations for all unsigned integer types.
> > I assume that it is not possible in C++ to write one specialization for all
> > unsigned integer type, but that a specialization for each unsigned integer type
> > must be created.
> > Since this software runs on different platforms, I wonder whether it is
> > possible to write a complete set of specializations in a platform independent way.

>
> > I first tried to write specializations for uint8_t, uint16_t, uint32_t and uint64_t
> > as defined in inttypes.h, but it turns out that on some platforms some
> > unsigned integer types are still missing. (Under Windows e.g.,
> > there is more than one 32-bit unsigned integer type.)
> > Types like size_t and clock_t map to different types on different platforms.
> > I wonder whether it is possible to create a complete list,
> > without using conditional code selection in the preprocessor.
> > Is the list "unsigned char, unsigned short, unsigned int, unsigned long and unsigned long long"
> > complete and without overlap (as far as specializations concern) for all platforms?
> > Should I add unsigned wchar_t, or is it covered already?

>
> > (I know that char needs special attention. I know how to handle that case.)

>
> Your list seems exhaustive, and "unsigned wchar_t" should be already
> covered by your list (after all, it should be just an unsigned integer
> somewhat bigger than char). But you'll eventually get more certain
> answers about this.
>
> About avoiding to create all those specializations, can you get along
> with duplicating the body of your template to include both algorithms,
> checking then for unsigned-ness at runtime via numeric_limits?
>
> The compiler could then optimize away the algorithm version that
> doesn't happen to be appropriate for each type - at least, I suppose
> so, I'd have to check if it works but I'm not so sure I will able to.


Sorry, I badly worded it because it's not that clear to me. Maybe that
check will be performed at compile-time (otherwise, the compiles
wouldn't be able to optimize away those parts).

Something new to experiment

--
Francesco S. Carta, http://fscode.altervista.org
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      10-13-2009
Fred Zwarts wrote:

> I have created a template function for a generic algorithm.
> For unsigned integer types, a small modification in the algorithm is
> needed, because I can't use negative values there.
> So, I want to make specializations for all unsigned integer types.


Maybe the following helps:

template < typename T >
struct is_signed {
static bool const value = 0 > T(-1);
};

> I assume that it is not possible in C++ to write one specialization for
> all unsigned integer type, but that a specialization for each unsigned
> integer type must be created.


No, but you could do:

template < typename T, bool IsSigned = is_signed<T>::value >
struct ...

and partially specialize that for <T,true> and <T,false>.

[...]


Best

Kai-Uwe Bux
 
Reply With Quote
 
Fred Zwarts
Guest
Posts: n/a
 
      10-13-2009
Kai-Uwe Bux wrote:
> Fred Zwarts wrote:
>
>> I have created a template function for a generic algorithm.
>> For unsigned integer types, a small modification in the algorithm is
>> needed, because I can't use negative values there.
>> So, I want to make specializations for all unsigned integer types.

>
> Maybe the following helps:
>
> template < typename T >
> struct is_signed {
> static bool const value = 0 > T(-1);
> };
>
>> I assume that it is not possible in C++ to write one specialization
>> for all unsigned integer type, but that a specialization for each
>> unsigned integer type must be created.

>
> No, but you could do:
>
> template < typename T, bool IsSigned = is_signed<T>::value >
> struct ...
>
> and partially specialize that for <T,true> and <T,false>.
>
> [...]


I tried something along these lines, but it turned out to my surprise,
that partial specializations are not allowed for template functions,
only for template classes/structs. Of course I could encapsulate the
function in a class and add a wrapper function...
 
Reply With Quote
 
Fred Zwarts
Guest
Posts: n/a
 
      10-13-2009
Francesco S. Carta wrote:
> "Fred Zwarts" <F.Zwa...@KVI.nl> wrote:
>> I have created a template function for a generic algorithm.
>> For unsigned integer types, a small modification in the algorithm is
>> needed,
>> because I can't use negative values there.
>> So, I want to make specializations for all unsigned integer types.
>> I assume that it is not possible in C++ to write one specialization
>> for all
>> unsigned integer type, but that a specialization for each unsigned
>> integer type
>> must be created.
>> Since this software runs on different platforms, I wonder whether it
>> is
>> possible to write a complete set of specializations in a platform
>> independent way.
>>
>> I first tried to write specializations for uint8_t, uint16_t,
>> uint32_t and uint64_t
>> as defined in inttypes.h, but it turns out that on some platforms
>> some
>> unsigned integer types are still missing. (Under Windows e.g.,
>> there is more than one 32-bit unsigned integer type.)
>> Types like size_t and clock_t map to different types on different
>> platforms.
>> I wonder whether it is possible to create a complete list,
>> without using conditional code selection in the preprocessor.
>> Is the list "unsigned char, unsigned short, unsigned int, unsigned
>> long and unsigned long long" complete and without overlap (as far as
>> specializations concern) for all platforms?
>> Should I add unsigned wchar_t, or is it covered already?
>>
>> (I know that char needs special attention. I know how to handle that
>> case.)

>
> Your list seems exhaustive, and "unsigned wchar_t" should be already
> covered by your list (after all, it should be just an unsigned integer
> somewhat bigger than char). But you'll eventually get more certain
> answers about this.
>
> About avoiding to create all those specializations, can you get along
> with duplicating the body of your template to include both algorithms,
> checking then for unsigned-ness at runtime via numeric_limits?
>
> The compiler could then optimize away the algorithm version that
> doesn't happen to be appropriate for each type - at least, I suppose
> so, I'd have to check if it works but I'm not so sure I will able to.
>
> Just an idea off the top of my head.


Thanks for the suggestion. I tried something along these lines.
It compiles and works as expected, but some compilers generate a lot
of warnings for those lines where tests are made for the sign of the
values during instantiations of unsigned types. Since this header is
included in may modules, I get many warnings which I cannot suppress
and which makes it difficult to find the more relevant warnings.
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      10-13-2009
Fred Zwarts wrote:

> Kai-Uwe Bux wrote:

[...]
>> No, but you could do:
>>
>> template < typename T, bool IsSigned = is_signed<T>::value >
>> struct ...
>>
>> and partially specialize that for <T,true> and <T,false>.
>>
>> [...]

>
> I tried something along these lines, but it turned out to my surprise,
> that partial specializations are not allowed for template functions,
> only for template classes/structs. Of course I could encapsulate the
> function in a class and add a wrapper function...


Yup. That is annoying. Maybe the most prominent case is specializing a
generic algorithm to take advantage of random access iterators. You have to
wrap the algorithm as a static member function of a class template, which
you can specialize in turn. I don't know why one has to go through the
extra complexity. (Come to think of it, I don't know whether this is slated
to change in C++0X.)


Best

Kai-Uwe Bux
 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      10-13-2009
"Fred Zwarts" <F.Zwa...@KVI.nl> wrote:
> Francesco S. Carta wrote:
> > "Fred Zwarts" <F.Zwa...@KVI.nl> wrote:
> >> I have created a template function for a generic algorithm.
> >> For unsigned integer types, a small modification in the algorithm is
> >> needed,
> >> because I can't use negative values there.
> >> So, I want to make specializations for all unsigned integer types.
> >> I assume that it is not possible in C++ to write one specialization
> >> for all
> >> unsigned integer type, but that a specialization for each unsigned
> >> integer type
> >> must be created.
> >> Since this software runs on different platforms, I wonder whether it
> >> is
> >> possible to write a complete set of specializations in a platform
> >> independent way.

>
> >> I first tried to write specializations for uint8_t, uint16_t,
> >> uint32_t and uint64_t
> >> as defined in inttypes.h, but it turns out that on some platforms
> >> some
> >> unsigned integer types are still missing. (Under Windows e.g.,
> >> there is more than one 32-bit unsigned integer type.)
> >> Types like size_t and clock_t map to different types on different
> >> platforms.
> >> I wonder whether it is possible to create a complete list,
> >> without using conditional code selection in the preprocessor.
> >> Is the list "unsigned char, unsigned short, unsigned int, unsigned
> >> long and unsigned long long" complete and without overlap (as far as
> >> specializations concern) for all platforms?
> >> Should I add unsigned wchar_t, or is it covered already?

>
> >> (I know that char needs special attention. I know how to handle that
> >> case.)

>
> > Your list seems exhaustive, and "unsigned wchar_t" should be already
> > covered by your list (after all, it should be just an unsigned integer
> > somewhat bigger than char). But you'll eventually get more certain
> > answers about this.

>
> > About avoiding to create all those specializations, can you get along
> > with duplicating the body of your template to include both algorithms,
> > checking then for unsigned-ness at runtime via numeric_limits?

>
> > The compiler could then optimize away the algorithm version that
> > doesn't happen to be appropriate for each type - at least, I suppose
> > so, I'd have to check if it works but I'm not so sure I will able to.

>
> > Just an idea off the top of my head.

>
> Thanks for the suggestion. I tried something along these lines.
> It compiles and works as expected, but some compilers generate a lot
> of warnings for those lines where tests are made for the sign of the
> values during instantiations of unsigned types. Since this header is
> included in may modules, I get many warnings which I cannot suppress
> and which makes it difficult to find the more relevant warnings.


I didn't think about those warnings.

Just in case: once you're assured that unsigned types will never make
it in your signed algo, couldn't you throw away those tests for
negativeness in the signed algo? Or perhaps change them so that they
don't raise warnings, if they're really needed.

For example, a check for some value being not negative can be
expressed as:
-------
if(val > -1) { /*...*/ };
-------

But also as either:
-------
if(val >= 0) { /* ... */ };
if(!(val < 0)) { /* ... */ };
-------

The latter two shouldn't raise any warning even if applied to unsigned
types, mmm, no, the compiler will eventually warn that those tests
always evaluate "true"...

Maybe the only way to avoid those warnings and taking advantage of the
templates is wrapping those algos within template classes, but as you
have already noted with Kai-Uwe, this is going to increase complexity
- and notation, too, I suspect.

Wait: what about this:
-------
if(val == 0 || val > 0) { /* ... */ };
-------

The above should issue no warning at all! Am I correct?
Compilers cannot be _that_ clever, can they?

Ahh. If you happen to find a compiler that warns on the above, try
this:
-------
T zero = 0; /* note: non-const... could a "volatile" help too, here?
*/
if(val >= zero) { /* ... */ };
-------

Anyway, gcc 3.4.5 never warned me for "always true/false" conditionals
- with "-Wall -pedantic" would them have been needed.

To avoid the weird part of my suggestion (duplicating the code in the
template body) one could make two different templates and wrap the
decision in a third one:
-------
#include <limits>

template<class T> void signed_algo(const T& one, const T& two) {
// ...
}

template<class T> void unsigned_algo(const T& one, const T& two) {
// ...
}

template<class T> void algo(const T& one, const T& two) {
if(std::numeric_limits<T>::is_signed) {
signed_algo(one, two);
} else {
unsigned_algo(one, two);
}
}
-------

Well, you surely have considered all of this already, I'm posting it
just for the occasional reader.

--
Francesco S. Carta, http://fscode.altervista.org
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      10-13-2009
On Oct 13, 12:31 pm, "Fred Zwarts" <F.Zwa...@KVI.nl> wrote:
> Kai-Uwe Bux wrote:
> > Fred Zwarts wrote:


> >> I have created a template function for a generic algorithm. For
> >> unsigned integer types, a small modification in the algorithm is
> >> needed, because I can't use negative values there. So, I want to
> >> make specializations for all unsigned integer types.


> > Maybe the following helps:


> > template < typename T >
> > struct is_signed {
> > static bool const value = 0 > T(-1);
> > };


> >> I assume that it is not possible in C++ to write one specialization
> >> for all unsigned integer type, but that a specialization for each
> >> unsigned integer type must be created.


> > No, but you could do:


> > template < typename T, bool IsSigned = is_signed<T>::value >
> > struct ...


> > and partially specialize that for <T,true> and <T,false>.


> > [...]


> I tried something along these lines, but it turned out to my surprise,
> that partial specializations are not allowed for template functions,
> only for template classes/structs. Of course I could encapsulate the
> function in a class and add a wrapper function...


Or you could forward to an overloaded function, something like:

template< bool > class Discrim {};

template< typename T >
void helper( T value, Discrim< false > )
{
// signed...
}

template< typename T >
void helper( T value, Discrim< true > )
{
// unsigned...
}

template< typename T >
void function( T value )
{
helper( value, Discrim< is_signed< T >::value >() ) ;
}

If you're doing a lot of this (or even more than once), you'll have
Discrim already written, and maybe even is_signed, so all that's left
is
the two overloads. (I don't claim that this is a better or a worse
solution than the partial specializations suggested by Kai-Uwe---I
generally use his method myself. But it's an alternative you might
consider.)

--
James Kanze
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      10-13-2009
On Oct 13, 12:37 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Fred Zwarts wrote:
> > Kai-Uwe Bux wrote:

> [...]
> >> No, but you could do:


> >> template < typename T, bool IsSigned = is_signed<T>::value >
> >> struct ...


> >> and partially specialize that for <T,true> and <T,false>.


> >> [...]


> > I tried something along these lines, but it turned out to my
> > surprise, that partial specializations are not allowed for template
> > functions, only for template classes/structs. Of course I could
> > encapsulate the function in a class and add a wrapper function...


> Yup. That is annoying. Maybe the most prominent case is specializing a
> generic algorithm to take advantage of random access iterators. You
> have to wrap the algorithm as a static member function of a class
> template, which you can specialize in turn.


Why don't you do like is done in most of the standard libraries:
overload the function with an additional argument:

template< typename RandomIterator >
void f( RandomIterator begin,
RandomIterator end,
std::random_access_iterator_tag )
{
}

template< typename OtherIterator >
void f( OtherIterator begin,
OtherIterator end,
std::input_iterator_tag )
{
}

template< typename Iterator >
void f( Iterator begin, Iterator end )
{
f( begin, end,
typename std::iterator_traits< Iterator
>::iterator_category() );

}

(I'm not sure that it's really that much simpler, but it is what I've
seen in the standard library. Note too that it does take advantage of
the inheritance in the iterator tags, so that a forward iterator will
automatically end up in the second overload, without having to
explicitly provide for it.)

--
James Kanze
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
(int) -> (unsigned) -> (int) or (unsigned) -> (int) -> (unsigned):I'll loose something? pozz C Programming 12 03-20-2011 11:32 PM
Addition for 'short' unsigned integer types badc0de4@gmail.com C Programming 3 06-15-2008 07:19 PM
Standard integer types vs <stdint.h> types euler70@gmail.com C Programming 163 01-28-2008 03:21 PM
conversion of signed integer to unsigned integer junky_fellow@yahoo.co.in C Programming 14 06-18-2005 02:29 PM
unsigned int const does not match const unsigned int Timo Freiberger C++ 3 10-30-2004 07:02 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57