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