fork(1) download
  1. #include <iostream>
  2. #include <limits>
  3.  
  4. using namespace std;
  5.  
  6. template<typename Desired, typename Given>
  7. constexpr Desired narrow_cast(Given arg) {
  8. static_assert(std::is_integral<Desired>::value, "Only integer types are supported");
  9. static_assert(std::is_integral<Given>::value, "Only integer types are supported");
  10.  
  11. auto min = std::numeric_limits<Desired>::min();
  12. auto max = std::numeric_limits<Desired>::max();
  13.  
  14. auto different_signs = std::is_signed<Given>::value xor std::is_signed<Desired>::value;
  15. if(sizeof(Desired) == sizeof(Given) && different_signs && arg < 0) {
  16. return 0;
  17. }
  18.  
  19. return
  20. min > arg? min:
  21. max < arg? max:
  22. arg;
  23. }
  24.  
  25. #define EXPECT_EQ(x, y) if (x != y) cout << "Failed test for " << #x \
  26. << "\nexpected: " << y \
  27. << "\n actual: " << x << endl; else
  28.  
  29. int main() {
  30. // to smaller type signed to signed
  31. EXPECT_EQ(narrow_cast<short>(100000), 32767);
  32. EXPECT_EQ(narrow_cast<short>(-100000), -32768);
  33. EXPECT_EQ(narrow_cast<short>(0), 0);
  34. EXPECT_EQ(narrow_cast<short>(-1), -1);
  35.  
  36. // to smaller type unsigned to unsigned
  37. EXPECT_EQ(narrow_cast<unsigned short>(100000u), 65535u);
  38. EXPECT_EQ(narrow_cast<unsigned short>(60000u), 60000u);
  39. EXPECT_EQ(narrow_cast<unsigned short>(0u), 0u);
  40. EXPECT_EQ(narrow_cast<unsigned short>(1u), 1u);
  41.  
  42. // to smaller type signed to signed to unsigned
  43. EXPECT_EQ(narrow_cast<unsigned short>(100000), 65535);
  44. EXPECT_EQ(narrow_cast<unsigned short>(-100000), 0);
  45. EXPECT_EQ(narrow_cast<unsigned short>(0), 0);
  46. EXPECT_EQ(narrow_cast<unsigned short>(-1), 0);
  47.  
  48. // to smaller type unsigned to signed
  49. EXPECT_EQ(narrow_cast<short>(100000u), 32767);
  50. EXPECT_EQ(narrow_cast<short>(60000u), 32767);
  51. EXPECT_EQ(narrow_cast<short>(0u), 0);
  52. EXPECT_EQ(narrow_cast<short>(1u), 1);
  53.  
  54. // to same size type signed to signed ////
  55. EXPECT_EQ(narrow_cast<int>(0x7fffffff), 0x7fffffff);
  56. EXPECT_EQ(narrow_cast<int>(-2147483648), -2147483648);
  57. EXPECT_EQ(narrow_cast<int>(0), 0);
  58. EXPECT_EQ(narrow_cast<int>(-1), -1);
  59.  
  60. // to same size type unsigned to unsigned
  61. EXPECT_EQ(narrow_cast<unsigned int>(0xffffffffu), 0xffffffffu);
  62. EXPECT_EQ(narrow_cast<unsigned int>(60000u), 60000u);
  63. EXPECT_EQ(narrow_cast<unsigned int>(0u), 0u);
  64. EXPECT_EQ(narrow_cast<unsigned int>(1u), 1u);
  65.  
  66. // to same size type signed to signed to unsigned
  67. EXPECT_EQ(narrow_cast<unsigned int>(0x7fffffff), 0x7fffffffu);
  68. EXPECT_EQ(narrow_cast<unsigned int>(-2147483648), 0u);
  69. EXPECT_EQ(narrow_cast<unsigned int>(0), 0u);
  70. EXPECT_EQ(narrow_cast<unsigned int>(-1), 0u);
  71.  
  72. // to same size type unsigned to signed
  73. EXPECT_EQ(narrow_cast<int>(0xffffffffu), 0x7fffffff);
  74. EXPECT_EQ(narrow_cast<int>(0x7fffffffu), 0x7fffffff);
  75. EXPECT_EQ(narrow_cast<int>(0x80000000u), 0x7fffffff);
  76. EXPECT_EQ(narrow_cast<int>(0u), 0);
  77. EXPECT_EQ(narrow_cast<int>(1u), 1);
  78.  
  79. // to bigger size type signed to signed ////
  80. EXPECT_EQ(narrow_cast<int64_t>(0x7fffffff), 0x7fffffffll);
  81. EXPECT_EQ(narrow_cast<int64_t>(-2147483648), -2147483648ll);
  82. EXPECT_EQ(narrow_cast<int64_t>(0), 0);
  83. EXPECT_EQ(narrow_cast<int64_t>(-1), -1ll);
  84.  
  85. // to bigger size type unsigned to unsigned
  86. EXPECT_EQ(narrow_cast<uint64_t>(0xffffffffu), 0xffffffffull);
  87. EXPECT_EQ(narrow_cast<uint64_t>(60000u), 60000ull);
  88. EXPECT_EQ(narrow_cast<uint64_t>(0u), 0ull);
  89. EXPECT_EQ(narrow_cast<uint64_t>(1u), 1ull);
  90.  
  91. // to bigger size type signed to signed to unsigned
  92. EXPECT_EQ(narrow_cast<uint64_t>(0x7fffffff), 0x7fffffffull);
  93. EXPECT_EQ(narrow_cast<uint64_t>(-2147483648), 0ull);
  94. EXPECT_EQ(narrow_cast<uint64_t>(0), 0ull);
  95. EXPECT_EQ(narrow_cast<uint64_t>(-1), 0ull);
  96.  
  97. // to bigger size type unsigned to signed
  98. EXPECT_EQ(narrow_cast<int64_t>(0xffffffffu), 0xffffffffll);
  99. EXPECT_EQ(narrow_cast<int64_t>(0x7fffffffu), 0x7fffffffll);
  100. EXPECT_EQ(narrow_cast<int64_t>(0x80000000u), 0x80000000ll);
  101. EXPECT_EQ(narrow_cast<int64_t>(0u), 0ll);
  102. EXPECT_EQ(narrow_cast<int64_t>(1u), 1ll);
  103.  
  104. return 0;
  105. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Failed test for narrow_cast<short>(100000u)
expected: 32767
  actual: -32768
Failed test for narrow_cast<short>(60000u)
expected: 32767
  actual: -32768
Failed test for narrow_cast<short>(0u)
expected: 0
  actual: -32768
Failed test for narrow_cast<short>(1u)
expected: 1
  actual: -32768
Failed test for narrow_cast<int>(0x7fffffffu)
expected: 2147483647
  actual: -2147483648
Failed test for narrow_cast<int>(0u)
expected: 0
  actual: -2147483648
Failed test for narrow_cast<int>(1u)
expected: 1
  actual: -2147483648
Failed test for narrow_cast<uint64_t>(-1)
expected: 0
  actual: 18446744073709551615