Upsigning or downsigning

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Damian

    Upsigning or downsigning

    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
  • tragomaskhalos

    #2
    Re: Upsigning or downsigning

    On 7 Apr, 17:40, Damian <damian.e...@gm ail.comwrote:
    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<typena me Tstruct 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<u nsigned T{\
    typedef T signed_t;\
    typedef unsigned T unsigned_t;\
    };
    MAKE_SVS_FOR(ch ar)
    // hmmm ... glossing over char vs signed char vs unsigned char ...
    MAKE_SVS_FOR(in t)
    MAKE_SVS_FOR(lo ng)
    MAKE_SVS_FOR(sh ort)
    // 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_varian ts<long>::signe d_t()) << '\n';
    std::cout << foo(sign_varian ts<long>::unsig ned_t()) << '\n';
    std::cout << foo(sign_varian ts<unsigned long>::signed_t ()) << '\n';
    std::cout << foo(sign_varian ts<unsigned long>::unsigned _t()) <<
    '\n';
    }
    /*
    output
    slong
    ulong
    slong
    ulong
    */
    </code>

    Obviously you'd use sign_variants inside a template.

    Comment

    Working...