Turi Create  4.0
type_traits.hpp
1 #ifndef TURI_TYPE_TRAITS_H_
2 #define TURI_TYPE_TRAITS_H_
3 
4 #include <type_traits>
5 #include <map>
6 #include <unordered_map>
7 #include <vector>
8 #include <tuple>
9 #include <core/generics/gl_vector.hpp>
10 #include <core/generics/gl_string.hpp>
11 
12 
13 namespace turi {
14 
15 template <typename T> class gl_vector;
16 
17 struct invalid_type {};
18 struct _invalid_type_base { typedef invalid_type type; };
19 
20 ////////////////////////////////////////////////////////////////////////////////
21 // Is it an std::vector?
22 
23 template<class... T> struct is_std_vector : public std::false_type {};
24 template<typename... A> struct is_std_vector<std::vector<A...> > : public std::true_type {};
25 
26 ////////////////////////////////////////////////////////////////////////////////
27 // Is it a gl_vector?
28 
29 template<class... T> struct is_gl_vector : public std::false_type {};
30 template<typename... A> struct is_gl_vector<gl_vector<A...> > : public std::true_type {};
31 
32 ////////////////////////////////////////////////////////////////////////////////
33 // Is it any sort of vector?
34 
35 template<typename... A> struct is_vector {
36  static constexpr bool value = (is_std_vector<A...>::value || is_gl_vector<A...>::value);
37 };
38 
39 ////////////////////////////////////////////////////////////////////////////////
40 // Is it any sort of deque?
41 
42 template<typename... T> struct is_deque : public std::false_type {};
43 template<typename... A> struct is_deque<std::deque<A...> > : public std::true_type {};
44 
45 ////////////////////////////////////////////////////////////////////////////////
46 // Is it any sort of list?
47 
48 template<typename... T> struct is_list : public std::false_type {};
49 template<typename... A> struct is_list<std::list<A...> > : public std::true_type {};
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 // Is it any of the above sequence operators?
53 
54 template<typename... A> struct is_sequence_container {
55  static constexpr bool value =
56  (is_vector<A...>::value || is_deque<A...>::value || is_list<A...>::value);
57 };
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 // Is it an std::map?
61 
62 template<class T> struct is_std_map : public std::false_type {};
63 template<typename... A> struct is_std_map<std::map<A...> > : public std::true_type {};
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 // Is it an std::unordered_map?
67 
68 template<class T> struct is_std_unordered_map : public std::false_type {};
69 template<typename... A> struct is_std_unordered_map<std::unordered_map<A...> > : public std::true_type {};
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 // Is it an boost::unordered_map?
73 
74 template<class T> struct is_boost_unordered_map : public std::false_type {};
75 template<typename... A> struct is_boost_unordered_map<boost::unordered_map<A...> > : public std::true_type {};
76 
77 ////////////////////////////////////////////////////////////////////////////////
78 // Is it any type of map?
79 
80 template<typename... A> struct is_map {
81  static constexpr bool value = (is_std_map<A...>::value
82  || is_std_unordered_map<A...>::value
83  || is_boost_unordered_map<A...>::value);
84 };
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 // Is it an std::pair?
88 
89 template<class T> struct is_std_pair : public std::false_type {};
90 template<typename... A> struct is_std_pair<std::pair<A...> > : public std::true_type {};
91 
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 // Is it an std::string?
95 
96 template<class... T> struct is_std_string : public std::false_type {};
97 template <> struct is_std_string<std::string> : public std::true_type {};
98 
99 ////////////////////////////////////////////////////////////////////////////////
100 // Is it a gl_string?
101 
102 template<class... T> struct is_gl_string : public std::false_type {};
103 template <> struct is_gl_string<gl_string> : public std::true_type {};
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 // Is it any sort of string?
107 
108 template<typename... A> struct is_string {
109  static constexpr bool value = (is_std_string<A...>::value || is_gl_string<A...>::value);
110 };
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 // Is tuple?
114 
115 template<class T> struct is_tuple : public std::false_type {};
116 template<typename... A> struct is_tuple<std::tuple<A...> > : public std::true_type {};
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 
120 /** Extract the first nested type from a template parameterized type
121  * definition; return invalid_type on failure.
122  *
123  * Example 1: second_nested_type<std::map<K, V, ...> >::type // Equal to K.
124  * Example 2: second_nested_type<std::pair<K, V> >::type // Equal to K.
125  * Example 3: second_nested_type<std::vector<K, ...> >::type // Equal to K.
126  */
127 template<class T> struct first_nested_type {
128  typedef invalid_type type;
129 };
130 
131 template<class T, typename... A, template <typename...> class C>
132 struct first_nested_type<C<T, A...> > {
133  typedef T type;
134 };
135 
136 template<class T, template <typename> class C>
137 struct first_nested_type<C<T> > {
138  typedef T type;
139 };
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 
143 /** Extract the second nested type from a template parameterized type
144  * definition; return invalid_type on failure.
145  *
146  * Example 1: second_nested_type<std::map<K, V, ...> >::type // Equal to V.
147  * Example 2: second_nested_type<std::pair<K, V> >::type // Equal to V.
148  */
149 template<class T> struct second_nested_type {
150  typedef invalid_type type;
151 };
152 
153 template<class T, class U, typename... A, template <typename...> class C>
154 struct second_nested_type<C<T, U, A...> > {
155  typedef U type;
156 };
157 
158 template<class T, class U, template <typename...> class C>
159 struct second_nested_type<C<T, U> > {
160  typedef U type;
161 };
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /* All true.
165  *
166  * Use: all_nested_true<P, Args...>::value. value is
167  * true if P<A>::value is true for all A in Args...
168  */
169 template <template <typename> class P, typename...>
170 struct all_true : public std::false_type {};
171 
172 template <template <typename> class P, class T>
173 struct all_true<P, T> {
174  static constexpr bool value = P<T>::value;
175 };
176 
177 template<template <typename> class P, class T, typename ... Args>
178 struct all_true<P, T, Args...> {
179  static constexpr bool value = (P<T>::value && all_true<P, Args...>::value);
180 };
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 
184 /* All nested true -- mainly useful for tuples.
185  *
186  * Use: all_nested_true<P, std::tuple<Args...> >::value. value is
187  * true if P<A>::value is true for all A in Args...
188  */
189 template <template <typename> class P, typename...> struct all_nested_true : public std::false_type {};
190 
191 template<template <typename> class P, template <typename...> class C, typename... Args>
192 struct all_nested_true<P, C<Args...> > {
193  static constexpr bool value = all_true<P, Args...>::value;
194 };
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 
198 /** Conditional test -- the use case here is that the test is not even
199  * instantiated if the condition fails. This has been useful to
200  * eliminate certain recursions.
201  *
202  * Use: conditional_test<bool c, Cond, Args...>::value. If c is
203  * true, then Cond<Args...> is instantiated and the value is equal to
204  * Cond<Args...>::value. If c is false, the value is false.
205  */
206 template <bool, template <typename...> class Cond, typename... Args> struct conditional_test
207  : public std::false_type {};
208 
209 template <template <typename...> class Cond, typename... Args>
210 struct conditional_test<true, Cond, Args...> {
211 
212  template <template <typename...> class _Cond, typename... _Args>
213  static constexpr bool _value(typename std::enable_if<_Cond<_Args...>::value, int>::type = 0) {
214  return true;
215  }
216 
217  template <template <typename...> class _Cond, typename... _Args>
218  static constexpr bool _value(typename std::enable_if<!_Cond<_Args...>::value, int>::type = 0) {
219  return false;
220  }
221 
222  static constexpr bool value = _value<Cond, Args...>();
223 };
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 // Int that fits in double
227 
228 template <typename T> struct fits_in_4bytes {
229  static constexpr bool value = (sizeof(T) <= 4);
230 };
231 
232 template <typename T> struct is_integer_in_4bytes {
233  static constexpr bool value = conditional_test<std::is_integral<T>::value, fits_in_4bytes, T>::value;
234 };
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 // Swallow to false. Conditional instantiation for static_assert statements.
238 
239 template<typename T> struct swallow_to_false : std::false_type {};
240 
241 ////////////////////////////////////////////////////////////////////////////////
242 // Remove all modifiers
243 //
244 template <typename T> struct base_type { typedef T type; };
245 template <typename T> struct base_type<T&> { typedef T type; };
246 template <typename T> struct base_type<const T&> { typedef T type; };
247 template <typename T> struct base_type<T&&> { typedef T type; };
248 }
249 
250 
251 #endif /* TURI_TYPE_TRAITS_H_ */
STL namespace.