fork download
  1. #include <limits>
  2. #include <type_traits>
  3. #include <iostream>
  4.  
  5. template <typename T> struct unsigned_integer_traits;
  6. template <> struct unsigned_integer_traits<unsigned char> {
  7. typedef signed char signed_type;
  8. };
  9. template <> struct unsigned_integer_traits<unsigned short int> {
  10. typedef signed short int signed_type;
  11. };
  12. template <> struct unsigned_integer_traits<unsigned int> {
  13. typedef signed int signed_type;
  14. };
  15. template <> struct unsigned_integer_traits<unsigned long int> {
  16. typedef signed long int signed_type;
  17. };
  18. template <> struct unsigned_integer_traits<unsigned long long int> {
  19. typedef signed long long int signed_type;
  20. };
  21.  
  22.  
  23. template <typename T>
  24. struct is_2complement_system {
  25. typedef typename unsigned_integer_traits<T>::signed_type signed_type;
  26. static const bool value = (static_cast<signed_type>(~(T()))
  27. == static_cast<signed_type>(-1));
  28. };
  29. template <typename T>
  30. const bool is_2complement_system<T>::value;
  31.  
  32. template <typename T, bool is_2complement_system_value>
  33. struct unsigned_to_signed_impl;
  34.  
  35. template <typename T>
  36. struct unsigned_to_signed_impl<T,true> {
  37. typedef typename unsigned_integer_traits<T>::signed_type signed_type;
  38. static signed_type convert(T value)
  39. {
  40. return static_cast<signed_type>(value);
  41. }
  42. };
  43.  
  44. template <typename T>
  45. struct unsigned_to_signed_impl<T,false> {
  46. typedef typename unsigned_integer_traits<T>::signed_type signed_type;
  47. static signed_type convert(T value)
  48. {
  49. // well do something complicated you don't care what
  50. return T(); // just for tests
  51. }
  52. };
  53.  
  54. template <typename T>
  55. typename unsigned_integer_traits<T>::signed_type unsigned_to_signed(T n)
  56. {
  57. return unsigned_to_signed_impl<T,is_2complement_system<T>::value>::convert(n);
  58. }
  59.  
  60. int main() {
  61. std::cout
  62. << unsigned_to_signed(100u) << '\n'
  63. << unsigned_to_signed(0xFFFFffff) << '\n'
  64. ;
  65.  
  66. }
Success #stdin #stdout 0s 2928KB
stdin
Standard input is empty
stdout
100
-1