Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::make_signed that accepts floating point types

I have a templated class that can only be instantiated for scalar types (integers, floats, etc.) and I want a member typedef to always be the signed variant of the type. That is:

unsigned int -> signed int
signed long long -> signed long long (already signed)
unsigned char -> signed char
float -> float
long double -> long double
etc...

Unfortunately, std::make_signed only works for integral types, not the floating point types. What is the simplest way to do this? I'm looking for something of the form using SignedT = ...;, to be part of my templated class with template parameter T already guaranteed to be scalar.

like image 544
LB-- Avatar asked May 04 '13 18:05

LB--


People also ask

Is Wchar_t signed?

wchar_t is unsigned. Corresponding assembly code says movzwl _BOM, %eax .

Is unsigned Type C++?

The unsigned keyword is a data type specifier, that makes a variable only represent non-negative integer numbers (positive numbers and zero). It can be applied only to the char , short , int and long types.


1 Answers

A simple template alias will do:

#include <type_traits>

template<typename T>
struct identity { using type = T; };

template<typename T>
using try_make_signed =
    typename std::conditional<
        std::is_integral<T>::value,
        std::make_signed<T>,
        identity<T>
        >::type;

And this is how you could test it:

int main()
{
    static_assert(::is_same<
        try_make_signed<unsigned int>::type, int
        >::value, "!");

    static_assert(std::is_same<
        try_make_signed<double>::type, double
        >::value, "!");
}

Here is a live example.

like image 64
Andy Prowl Avatar answered Sep 27 '22 20:09

Andy Prowl