-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathis_range_based.hpp
More file actions
70 lines (53 loc) · 2.38 KB
/
is_range_based.hpp
File metadata and controls
70 lines (53 loc) · 2.38 KB
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
#include <type_traits>
namespace cppcode { namespace common {
namespace is_range_based_helper {
template <typename...> using void_t = void;
// has begin()
template <typename T, typename = void>
struct has_begin : std::false_type {};
template <typename T>
struct has_begin<T, void_t<decltype(std::declval<T>().begin())>> : std::true_type {};
// has end()
template <typename T, typename = void>
struct has_end : std::false_type {};
template <typename T>
struct has_end<T, void_t<decltype(std::declval<T>().end())>> : std::true_type {};
// has iterator
template <typename T, typename = void>
struct has_iterator : std::false_type {};
template <typename T>
struct has_iterator<T, void_t<typename T::iterator>>
{
typedef decltype(*(std::declval<typename T::iterator>())) derefType;
static const bool value = std::is_same<T, typename std::remove_cv<typename std::remove_reference<derefType>::type>::type>::value;
};
template <typename T>
const bool has_iterator<T, void_t<typename T::iterator>>::value;
// has first
template <typename T, typename = void>
struct has_first : std::false_type {};
template <typename T>
struct has_first<T, void_t<decltype(T::first)>> : std::true_type {};
// has second
template <typename T, typename = void>
struct has_second : std::false_type {};
template <typename T>
struct has_second<T, void_t<decltype(T::second)>> : std::true_type {};
// has pre-incrementable iterator
template <typename T, typename = void>
struct has_pre_inc_iterator : std::false_type {};
template <typename T>
struct has_pre_inc_iterator<T, void_t<decltype(++(std::declval<typename T::iterator>()))>> : std::true_type {};
}
// is_range_based
template <typename T>
struct is_range_based
{
static const bool value = is_range_based_helper::has_begin<T>::value &&
is_range_based_helper::has_end<T>::value &&
is_range_based_helper::has_iterator<T>::value &&
is_range_based_helper::has_pre_inc_iterator<T>::value;
};
template <typename T>
const bool is_range_based<T>::value;
}}