Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Upsigning or downsigning

Reply
Thread Tools

Upsigning or downsigning

 
 
Damian
Guest
Posts: n/a
 
      04-07-2008
Is there any way to manipulate a template parameter to change its
signedness?

For example,

template <typename T>
void foo(signed T a, unsigned T b) {

}

defines a templated function that is instantiated with a base numeric
type (e.g. int or long) but is referred by signed and unsigned
variants.

Also, how do I convert a typename to signed or unsigned? For example,
if I had some variable k I wanted to cast to the unsigned variant of
type T, I'd like to be able to do

j = (unsigned_type(T))k

but I'm not sure if it's possible to do something like that. Is there
anyway to "upsign" (i.e. convert a numeric type to signed) or
"downsign" (i.e. convert a numeric type to unsigned) similar to how
one might upcast or downcast a number?

Thanks!

Damian Eads
 
Reply With Quote
 
 
 
 
Fei Liu
Guest
Posts: n/a
 
      04-07-2008
Damian wrote:
> Is there any way to manipulate a template parameter to change its
> signedness?
>
> For example,
>
> template <typename T>
> void foo(signed T a, unsigned T b) {
>
> }
>
> defines a templated function that is instantiated with a base numeric
> type (e.g. int or long) but is referred by signed and unsigned
> variants.
>
> Also, how do I convert a typename to signed or unsigned? For example,
> if I had some variable k I wanted to cast to the unsigned variant of
> type T, I'd like to be able to do
>
> j = (unsigned_type(T))k
>
> but I'm not sure if it's possible to do something like that. Is there
> anyway to "upsign" (i.e. convert a numeric type to signed) or
> "downsign" (i.e. convert a numeric type to unsigned) similar to how
> one might upcast or downcast a number?
>
> Thanks!
>
> Damian Eads


Yes, because signed-ness is part of a function signature that function
overloading uses. You can devise a 'type-of' class template to determine
if a type is signed or unsigned at compile time.

Fei
 
Reply With Quote
 
 
 
 
Abhishek Padmanabh
Guest
Posts: n/a
 
      04-07-2008
On Apr 7, 9:40*pm, Damian <(E-Mail Removed)> wrote:
> Is there any way to manipulate a template parameter to change its
> signedness?
>
> For example,
>
> * template <typename T>
> * void foo(signed T a, unsigned T b) {
>
> * }
>
> defines a templated function that is instantiated with a base numeric
> type (e.g. int or long) but is referred by signed and unsigned
> variants.


Would have, probably, worked if T worked like a macro replacement but
it does not.

>
> Also, how do I convert a typename to signed or unsigned? For example,
> if I had some variable k I wanted to cast to the unsigned variant of
> type T, I'd like to be able to do
>
> * *j = (unsigned_type(T))k
>
> but I'm not sure if it's possible to do something like that. Is there
> anyway to "upsign" (i.e. convert a numeric type to signed) or
> "downsign" (i.e. convert a numeric type to unsigned) similar to how
> one might upcast or downcast a number?


No that I know of, but there may be. I think what you are trying to do
is to force the template to work with unsigned types only. There could
be two ways in which you can accomplish that depending on what you are
actually trying to do.

1) Don't let the template instantiate if the type is a signed type
with something like this, if you want callers to not pass signed
types:

template<typename T>
void func(T t)
{
BOOST_STATIC_ASSERT(boost::is_signed<T>::value);
//rest of the code, T will be signed assuming T is a integral type
//might put an assert if not boost::is_integral or as required
}

2) Provide overloads for the signed types that redirect the call to
the template with static_cast or explicitly specifying instantiation
type to make the argument unsigned:

template<typename T>
void func(T t)
{
//rest code
}

void func(int i) { func<unsigned int>(i);}
void func(char c) { func<unsigned char>(c);}

 
Reply With Quote
 
tragomaskhalos
Guest
Posts: n/a
 
      04-07-2008
On 7 Apr, 17:40, Damian <(E-Mail Removed)> wrote:
> Also, how do I convert a typename to signed or unsigned? For example,
> if I had some variable k I wanted to cast to the unsigned variant of
> type T, I'd like to be able to do
>
> * *j = (unsigned_type(T))k
>
> but I'm not sure if it's possible to do something like that. Is there
> anyway to "upsign" (i.e. convert a numeric type to signed) or
> "downsign" (i.e. convert a numeric type to unsigned) similar to how
> one might upcast or downcast a number?
>


How about this ?
<code>
template<typename T> struct sign_variants {};
#define MAKE_SVS_FOR(T) \
template<> struct sign_variants<T> {\
typedef T signed_t;\
typedef unsigned T unsigned_t;\
};\
template<> struct sign_variants<unsigned T> {\
typedef T signed_t;\
typedef unsigned T unsigned_t;\
};
MAKE_SVS_FOR(char)
// hmmm ... glossing over char vs signed char vs unsigned char ...
MAKE_SVS_FOR(int)
MAKE_SVS_FOR(long)
MAKE_SVS_FOR(short)
// add any other flavours your compiler supports

#undef MAKE_SVS_FOR

// then e.g.
#include <iostream>

const char* foo(long x)
{ return "slong"; }
const char* foo(unsigned long x)
{ return "ulong"; }

void signedness()
{
std::cout << foo(sign_variants<long>::signed_t()) << '\n';
std::cout << foo(sign_variants<long>::unsigned_t()) << '\n';
std::cout << foo(sign_variants<unsigned long>::signed_t()) << '\n';
std::cout << foo(sign_variants<unsigned long>::unsigned_t()) <<
'\n';
}
/*
output
slong
ulong
slong
ulong
*/
</code>

Obviously you'd use sign_variants inside a template.
 
Reply With Quote
 
Damian
Guest
Posts: n/a
 
      04-07-2008
On Apr 7, 10:30 am, Abhishek Padmanabh <(E-Mail Removed)>
wrote:
> On Apr 7, 9:40 pm, Damian <(E-Mail Removed)> wrote:
>
> > Is there any way to manipulate a template parameter to change its
> > signedness?

>
> > For example,

>
> > template <typename T>
> > void foo(signed T a, unsigned T b) {

>
> > }

>
> > defines a templated function that is instantiated with a base numeric
> > type (e.g. int or long) but is referred by signed and unsigned
> > variants.

>
> Would have, probably, worked if T worked like a macro replacement but
> it does not.
>
> > Also, how do I convert a typename to signed or unsigned? For example,
> > if I had some variable k I wanted to cast to the unsigned variant of
> > type T, I'd like to be able to do

>
> > j = (unsigned_type(T))k

>
> > but I'm not sure if it's possible to do something like that. Is there
> > anyway to "upsign" (i.e. convert a numeric type to signed) or
> > "downsign" (i.e. convert a numeric type to unsigned) similar to how
> > one might upcast or downcast a number?

>
> No that I know of, but there may be. I think what you are trying to do
> is to force the template to work with unsigned types only. There could
> be two ways in which you can accomplish that depending on what you are
> actually trying to do.
>
> 1) Don't let the template instantiate if the type is a signed type
> with something like this, if you want callers to not pass signed
> types:
>
> template<typename T>
> void func(T t)
> {
> BOOST_STATIC_ASSERT(boost::is_signed<T>::value);
> //rest of the code, T will be signed assuming T is a integral type
> //might put an assert if not boost::is_integral or as required
>
> }


Ah, so passing an unsigned type here generates an assertion. I see
that you address how to handle overloading with signed types below.

> 2) Provide overloads for the signed types that redirect the call to
> the template with static_cast or explicitly specifying instantiation
> type to make the argument unsigned:
>
> template<typename T>
> void func(T t)
> {
> //rest code
>
> }
>
> void func(int i) { func<unsigned int>(i);}
> void func(char c) { func<unsigned char>(c);}


Since I was asked by several people already for an example. I will
give one. Suppose you want to take the absolute value on a value of
any integer type. The absolute value of an unsigned would just leave
the value unchanged and the absolute value of a signed type would set
the signed bit to naught.
 
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




Advertisments