fork download
  1. #include <limits>
  2. #include <utility>
  3. #include <iostream>
  4.  
  5. template <typename T>
  6. struct is_integral {
  7. static bool const value = std::numeric_limits<T>::is_integer;
  8. };
  9.  
  10. template <typename T>
  11. struct is_real {
  12. static bool const value = not is_integral<T>::value;
  13. };
  14.  
  15. template <typename T, typename L, typename R>
  16. struct are_all_integral {
  17. static bool const value = is_integral<T>::value and
  18. is_integral<L>::value and
  19. is_integral<R>::value;
  20. };
  21.  
  22. template <typename T, typename L, typename R>
  23. struct is_any_real {
  24. static bool const value = is_real<T>::value or
  25. is_real<L>::value or
  26. is_real<R>::value;
  27. };
  28.  
  29.  
  30. template <typename T, typename L, typename R>
  31. typename std::enable_if<are_all_integral<T, L, R>::value, bool>::type
  32. inRange(T x, L start, R end) {
  33. typedef typename std::common_type<T, L, R>::type common;
  34. std::cout << " inRange(" << x << ", " << start << ", " << end << ") -> Integral\n";
  35. return static_cast<common>(x) >= static_cast<common>(start) and
  36. static_cast<common>(x) <= static_cast<common>(end);
  37. }
  38.  
  39. template <typename T, typename L, typename R>
  40. typename std::enable_if<is_any_real<T, L, R>::value, bool>::type
  41. inRange(T x, L start, R end) {
  42. typedef typename std::common_type<T, L, R>::type common;
  43. std::cout << " inRange(" << x << ", " << start << ", " << end << ") -> Real\n";
  44. return static_cast<common>(x) >= static_cast<common>(start) and
  45. static_cast<common>(x) <= static_cast<common>(end);
  46. }
  47.  
  48. int main() {
  49. std::cout << "Pure cases\n";
  50. inRange(1, 2, 3);
  51. inRange(1.5, 2.5, 3.5);
  52.  
  53. std::cout << "Mixed int/unsigned\n";
  54. inRange(1u, 2, 3);
  55. inRange(1, 2u, 3);
  56. inRange(1, 2, 3u);
  57.  
  58. std::cout << "Mixed float/double\n";
  59. inRange(1.5f, 2.5, 3.5);
  60. inRange(1.5, 2.5f, 3.5);
  61. inRange(1.5, 2.5, 3.5f);
  62.  
  63. std::cout << "Mixed int/double\n";
  64. inRange(1.5, 2, 3);
  65. inRange(1, 2.5, 3);
  66. inRange(1, 2, 3.5);
  67.  
  68. std::cout << "Mixed int/double, with more doubles\n";
  69. inRange(1.5, 2.5, 3);
  70. inRange(1.5, 2, 3.5);
  71. inRange(1, 2.5, 3.5);
  72. }
Success #stdin #stdout 0s 2832KB
stdin
Standard input is empty
stdout
Pure cases
  inRange(1, 2, 3) -> Integral
  inRange(1.5, 2.5, 3.5) -> Real
Mixed int/unsigned
  inRange(1, 2, 3) -> Integral
  inRange(1, 2, 3) -> Integral
  inRange(1, 2, 3) -> Integral
Mixed float/double
  inRange(1.5, 2.5, 3.5) -> Real
  inRange(1.5, 2.5, 3.5) -> Real
  inRange(1.5, 2.5, 3.5) -> Real
Mixed int/double
  inRange(1.5, 2, 3) -> Real
  inRange(1, 2.5, 3) -> Real
  inRange(1, 2, 3.5) -> Real
Mixed int/double, with more doubles
  inRange(1.5, 2.5, 3) -> Real
  inRange(1.5, 2, 3.5) -> Real
  inRange(1, 2.5, 3.5) -> Real