Advertisement
Dukales

type-safe constexpr comparison of ints

May 25th, 2013
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.34 KB | None | 0 0
  1. // http://stackoverflow.com/questions/16752954/
  2. #include <type_traits>
  3. #include <limits>
  4. #include <utility>
  5.  
  6. #include <cstdint>
  7. #include <cstdlib>
  8.  
  9. template< typename L, typename R >
  10. inline constexpr
  11. typename std::enable_if< (std::is_signed< L >::value && !std::is_signed< R >::value), bool >::type
  12. less(L const & lhs, R const & rhs)
  13. {
  14.     static_assert(std::is_integral< L >::value,
  15.                   "lhs value must be of integral type");
  16.     static_assert(std::is_integral< R >::value,
  17.                   "rhs value must be of integral type");
  18.     using T = typename std::common_type< L, R >::type;
  19.     return (lhs < static_cast< L >(0)) || (static_cast< T const & >(lhs) < static_cast< T const & >(rhs));
  20. }
  21.  
  22. template< typename L, typename R >
  23. inline constexpr
  24. typename std::enable_if< (!std::is_signed< L >::value && std::is_signed< R >::value), bool >::type
  25. less(L const & lhs, R const & rhs)
  26. {
  27.     static_assert(std::is_integral< L >::value,
  28.                   "lhs value must be of integral type");
  29.     static_assert(std::is_integral< R >::value,
  30.                   "rhs value must be of integral type");
  31.     using T = typename std::common_type< L, R >::type;
  32.     return !(rhs < static_cast< R >(0)) && (static_cast< T const & >(lhs) < static_cast< T const & >(rhs));
  33. }
  34.  
  35. template< typename L, typename R >
  36. inline constexpr
  37. typename std::enable_if< (std::is_signed< L >::value == std::is_signed< R >::value), bool >::type
  38. less(L const & lhs, R const & rhs)
  39. {
  40.     static_assert(std::is_integral< L >::value,
  41.                   "lhs value must be of integral type");
  42.     static_assert(std::is_integral< R >::value,
  43.                   "rhs value must be of integral type");
  44.     return lhs < rhs;
  45. }
  46.  
  47. namespace
  48. {
  49.  
  50. static_assert(less(1, 2), "0");
  51. static_assert(less(-1, std::numeric_limits< std::uintmax_t >::max()), "1");
  52. static_assert(less< std::int8_t, std::uintmax_t >(-1, std::numeric_limits< std::uintmax_t >::max()), "2");
  53. static_assert(less< std::intmax_t, std::uint8_t >(-1, std::numeric_limits< std::uint8_t >::max()), "3");
  54. #pragma GCC diagnostic push
  55. #pragma GCC diagnostic ignored "-Wsign-compare"
  56. static_assert(!(-1 < std::numeric_limits< unsigned long >::max()), "4");
  57. #pragma GCC diagnostic pop
  58. static_assert(less(-1, std::numeric_limits< unsigned long >::max()), "5");
  59.  
  60. }
  61.  
  62. int main()
  63. {
  64.         return EXIT_SUCCESS;
  65. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement