fork download
  1. #include <limits>
  2. #include <type_traits>
  3. #include <algorithm>
  4.  
  5. using std::min;
  6. using std::max;
  7.  
  8. template <typename T>
  9. constexpr auto digits = std::numeric_limits<T>::digits;
  10.  
  11. template <typename T, typename U, std::enable_if_t<std::is_unsigned<T>{} && std::is_unsigned<U>{} && !std::is_same<T, U>{}, int> = 0> // unsigned, unsigned
  12. constexpr auto min(T t, U u)
  13. {
  14. using result_t = std::conditional_t<digits<U> < digits<T>, U, T>; // kleinerer Typ
  15. return u < t ? static_cast<result_t>(u) : static_cast<result_t>(t);
  16. }
  17. template <typename T, typename U, std::enable_if_t<std::is_signed<T>{} && std::is_signed<U>{} && !std::is_same<T, U>{}, int> = 0> // signed, signed
  18. constexpr auto min(T t, U u)
  19. {
  20. using result_t = std::conditional_t<digits<T> < digits<U>, U, T>; // größerer Typ
  21. return u < t ? static_cast<result_t>(u) : static_cast<result_t>(t);
  22. }
  23. template <typename T, typename U, std::enable_if_t<std::is_unsigned<T>{} && std::is_signed<U>{}, int> = 0> // unsigned, signed
  24. constexpr auto min(T t, U u)
  25. {
  26. using result_t = U;
  27. return u < 0 || static_cast<std::make_unsigned_t<U>>(u) < t ? static_cast<result_t>(u) : static_cast<result_t>(t);
  28. }
  29. template <typename T, typename U, std::enable_if_t<std::is_signed<T>{} && std::is_unsigned<U>{}, int> = 0> // signed, unsigned
  30. constexpr auto min(T t, U u)
  31. {
  32. using result_t = T;
  33. return t > 0 && u < static_cast<std::make_unsigned_t<T>>(t) ? static_cast<result_t>(u) : static_cast<result_t>(t);
  34. }
  35.  
  36. template <typename T, typename U, std::enable_if_t<std::is_unsigned<T>{} == std::is_unsigned<U>{} && !std::is_same<T, U>{}, int> = 0> // unsigned, unsigned oder signed, signed
  37. constexpr auto max(T t, U u)
  38. {
  39. using result_t = std::conditional_t<digits<U> < digits<T>, U, T>; // größerer Typ
  40. return u < t ? static_cast<result_t>(u) : static_cast<result_t>(t);
  41. }
  42. template <typename T, typename U, std::enable_if_t<std::is_unsigned<T>{} && std::is_signed<U>{}, int> = 0> // unsigned, signed
  43. constexpr auto max(T t, U u)
  44. {
  45. using result_t = std::conditional_t<digits<T> < digits<std::make_unsigned_t<U>>, std::make_unsigned_t<U>, T>;
  46. return u >= 0 && t < static_cast<std::make_unsigned_t<U>>(u) ? static_cast<result_t>(u) : static_cast<result_t>(t);
  47. }
  48. template <typename T, typename U, std::enable_if_t<std::is_signed<T>{} && std::is_unsigned<U>{}, int> = 0> // signed, unsigned
  49. constexpr auto max(T t, U u)
  50. {
  51. using result_t = std::conditional_t<digits<U> < digits<std::make_unsigned_t<T>>, std::make_unsigned_t<T>, U>;
  52. return t < 0 || static_cast<std::make_unsigned_t<T>>(t) < u ? static_cast<result_t>(u) : static_cast<result_t>(t);
  53. }
  54.  
  55. int main()
  56. {
  57. constexpr char c = 1;
  58. constexpr unsigned short us = 2;
  59. constexpr int i = 3;
  60. constexpr long long ll = 4;
  61. constexpr unsigned long long ull = 5;
  62. static_assert( min( c, us ) == 1, "" );
  63. static_assert( std::is_same<decltype(min( c, us )), char>{}, "" );
  64. static_assert( max( c, us ) == 2, "" );
  65. static_assert( std::is_same<decltype(max( c, us )), unsigned short>{}, "" );
  66. static_assert( min( ll, ull ) == 4, "" );
  67. static_assert( std::is_same<decltype(min( ll, ull )), long long>{}, "" );
  68. static_assert( max( ll, ull ) == 5, "" );
  69. static_assert( std::is_same<decltype(max( ll, ull )), unsigned long long>{}, "" );
  70. }
Success #stdin #stdout 0s 3452KB
stdin
Standard input is empty
stdout
Standard output is empty