diff options
Diffstat (limited to 'include/utils/TypeHelpers.h')
-rw-r--r-- | include/utils/TypeHelpers.h | 336 |
1 files changed, 0 insertions, 336 deletions
diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h deleted file mode 100644 index 2a2522722..000000000 --- a/include/utils/TypeHelpers.h +++ /dev/null | |||
@@ -1,336 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #ifndef ANDROID_TYPE_HELPERS_H | ||
18 | #define ANDROID_TYPE_HELPERS_H | ||
19 | |||
20 | #include <new> | ||
21 | #include <type_traits> | ||
22 | |||
23 | #include <stdint.h> | ||
24 | #include <string.h> | ||
25 | #include <sys/types.h> | ||
26 | |||
27 | // --------------------------------------------------------------------------- | ||
28 | |||
29 | namespace android { | ||
30 | |||
31 | /* | ||
32 | * Types traits | ||
33 | */ | ||
34 | |||
35 | template <typename T> struct trait_trivial_ctor { enum { value = false }; }; | ||
36 | template <typename T> struct trait_trivial_dtor { enum { value = false }; }; | ||
37 | template <typename T> struct trait_trivial_copy { enum { value = false }; }; | ||
38 | template <typename T> struct trait_trivial_move { enum { value = false }; }; | ||
39 | template <typename T> struct trait_pointer { enum { value = false }; }; | ||
40 | template <typename T> struct trait_pointer<T*> { enum { value = true }; }; | ||
41 | |||
42 | template <typename TYPE> | ||
43 | struct traits { | ||
44 | enum { | ||
45 | // whether this type is a pointer | ||
46 | is_pointer = trait_pointer<TYPE>::value, | ||
47 | // whether this type's constructor is a no-op | ||
48 | has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value, | ||
49 | // whether this type's destructor is a no-op | ||
50 | has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value, | ||
51 | // whether this type type can be copy-constructed with memcpy | ||
52 | has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value, | ||
53 | // whether this type can be moved with memmove | ||
54 | has_trivial_move = is_pointer || trait_trivial_move<TYPE>::value | ||
55 | }; | ||
56 | }; | ||
57 | |||
58 | template <typename T, typename U> | ||
59 | struct aggregate_traits { | ||
60 | enum { | ||
61 | is_pointer = false, | ||
62 | has_trivial_ctor = | ||
63 | traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor, | ||
64 | has_trivial_dtor = | ||
65 | traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor, | ||
66 | has_trivial_copy = | ||
67 | traits<T>::has_trivial_copy && traits<U>::has_trivial_copy, | ||
68 | has_trivial_move = | ||
69 | traits<T>::has_trivial_move && traits<U>::has_trivial_move | ||
70 | }; | ||
71 | }; | ||
72 | |||
73 | #define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \ | ||
74 | template<> struct trait_trivial_ctor< T > { enum { value = true }; }; | ||
75 | |||
76 | #define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \ | ||
77 | template<> struct trait_trivial_dtor< T > { enum { value = true }; }; | ||
78 | |||
79 | #define ANDROID_TRIVIAL_COPY_TRAIT( T ) \ | ||
80 | template<> struct trait_trivial_copy< T > { enum { value = true }; }; | ||
81 | |||
82 | #define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \ | ||
83 | template<> struct trait_trivial_move< T > { enum { value = true }; }; | ||
84 | |||
85 | #define ANDROID_BASIC_TYPES_TRAITS( T ) \ | ||
86 | ANDROID_TRIVIAL_CTOR_TRAIT( T ) \ | ||
87 | ANDROID_TRIVIAL_DTOR_TRAIT( T ) \ | ||
88 | ANDROID_TRIVIAL_COPY_TRAIT( T ) \ | ||
89 | ANDROID_TRIVIAL_MOVE_TRAIT( T ) | ||
90 | |||
91 | // --------------------------------------------------------------------------- | ||
92 | |||
93 | /* | ||
94 | * basic types traits | ||
95 | */ | ||
96 | |||
97 | ANDROID_BASIC_TYPES_TRAITS( void ) | ||
98 | ANDROID_BASIC_TYPES_TRAITS( bool ) | ||
99 | ANDROID_BASIC_TYPES_TRAITS( char ) | ||
100 | ANDROID_BASIC_TYPES_TRAITS( unsigned char ) | ||
101 | ANDROID_BASIC_TYPES_TRAITS( short ) | ||
102 | ANDROID_BASIC_TYPES_TRAITS( unsigned short ) | ||
103 | ANDROID_BASIC_TYPES_TRAITS( int ) | ||
104 | ANDROID_BASIC_TYPES_TRAITS( unsigned int ) | ||
105 | ANDROID_BASIC_TYPES_TRAITS( long ) | ||
106 | ANDROID_BASIC_TYPES_TRAITS( unsigned long ) | ||
107 | ANDROID_BASIC_TYPES_TRAITS( long long ) | ||
108 | ANDROID_BASIC_TYPES_TRAITS( unsigned long long ) | ||
109 | ANDROID_BASIC_TYPES_TRAITS( float ) | ||
110 | ANDROID_BASIC_TYPES_TRAITS( double ) | ||
111 | |||
112 | // --------------------------------------------------------------------------- | ||
113 | |||
114 | |||
115 | /* | ||
116 | * compare and order types | ||
117 | */ | ||
118 | |||
119 | template<typename TYPE> inline | ||
120 | int strictly_order_type(const TYPE& lhs, const TYPE& rhs) { | ||
121 | return (lhs < rhs) ? 1 : 0; | ||
122 | } | ||
123 | |||
124 | template<typename TYPE> inline | ||
125 | int compare_type(const TYPE& lhs, const TYPE& rhs) { | ||
126 | return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs); | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * create, destroy, copy and move types... | ||
131 | */ | ||
132 | |||
133 | template<typename TYPE> inline | ||
134 | void construct_type(TYPE* p, size_t n) { | ||
135 | if (!traits<TYPE>::has_trivial_ctor) { | ||
136 | while (n > 0) { | ||
137 | n--; | ||
138 | new(p++) TYPE; | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
143 | template<typename TYPE> inline | ||
144 | void destroy_type(TYPE* p, size_t n) { | ||
145 | if (!traits<TYPE>::has_trivial_dtor) { | ||
146 | while (n > 0) { | ||
147 | n--; | ||
148 | p->~TYPE(); | ||
149 | p++; | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | template<typename TYPE> | ||
155 | typename std::enable_if<traits<TYPE>::has_trivial_copy>::type | ||
156 | inline | ||
157 | copy_type(TYPE* d, const TYPE* s, size_t n) { | ||
158 | memcpy(d,s,n*sizeof(TYPE)); | ||
159 | } | ||
160 | |||
161 | template<typename TYPE> | ||
162 | typename std::enable_if<!traits<TYPE>::has_trivial_copy>::type | ||
163 | inline | ||
164 | copy_type(TYPE* d, const TYPE* s, size_t n) { | ||
165 | while (n > 0) { | ||
166 | n--; | ||
167 | new(d) TYPE(*s); | ||
168 | d++, s++; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | template<typename TYPE> inline | ||
173 | void splat_type(TYPE* where, const TYPE* what, size_t n) { | ||
174 | if (!traits<TYPE>::has_trivial_copy) { | ||
175 | while (n > 0) { | ||
176 | n--; | ||
177 | new(where) TYPE(*what); | ||
178 | where++; | ||
179 | } | ||
180 | } else { | ||
181 | while (n > 0) { | ||
182 | n--; | ||
183 | *where++ = *what; | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | |||
188 | template<typename TYPE> | ||
189 | struct use_trivial_move : public std::integral_constant<bool, | ||
190 | (traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) | ||
191 | || traits<TYPE>::has_trivial_move | ||
192 | > {}; | ||
193 | |||
194 | template<typename TYPE> | ||
195 | typename std::enable_if<use_trivial_move<TYPE>::value>::type | ||
196 | inline | ||
197 | move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { | ||
198 | memmove(d, s, n*sizeof(TYPE)); | ||
199 | } | ||
200 | |||
201 | template<typename TYPE> | ||
202 | typename std::enable_if<!use_trivial_move<TYPE>::value>::type | ||
203 | inline | ||
204 | move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { | ||
205 | d += n; | ||
206 | s += n; | ||
207 | while (n > 0) { | ||
208 | n--; | ||
209 | --d, --s; | ||
210 | if (!traits<TYPE>::has_trivial_copy) { | ||
211 | new(d) TYPE(*s); | ||
212 | } else { | ||
213 | *d = *s; | ||
214 | } | ||
215 | if (!traits<TYPE>::has_trivial_dtor) { | ||
216 | s->~TYPE(); | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | template<typename TYPE> | ||
222 | typename std::enable_if<use_trivial_move<TYPE>::value>::type | ||
223 | inline | ||
224 | move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { | ||
225 | memmove(d, s, n*sizeof(TYPE)); | ||
226 | } | ||
227 | |||
228 | template<typename TYPE> | ||
229 | typename std::enable_if<!use_trivial_move<TYPE>::value>::type | ||
230 | inline | ||
231 | move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { | ||
232 | while (n > 0) { | ||
233 | n--; | ||
234 | if (!traits<TYPE>::has_trivial_copy) { | ||
235 | new(d) TYPE(*s); | ||
236 | } else { | ||
237 | *d = *s; | ||
238 | } | ||
239 | if (!traits<TYPE>::has_trivial_dtor) { | ||
240 | s->~TYPE(); | ||
241 | } | ||
242 | d++, s++; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | // --------------------------------------------------------------------------- | ||
247 | |||
248 | /* | ||
249 | * a key/value pair | ||
250 | */ | ||
251 | |||
252 | template <typename KEY, typename VALUE> | ||
253 | struct key_value_pair_t { | ||
254 | typedef KEY key_t; | ||
255 | typedef VALUE value_t; | ||
256 | |||
257 | KEY key; | ||
258 | VALUE value; | ||
259 | key_value_pair_t() { } | ||
260 | key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { } | ||
261 | key_value_pair_t& operator=(const key_value_pair_t& o) { | ||
262 | key = o.key; | ||
263 | value = o.value; | ||
264 | return *this; | ||
265 | } | ||
266 | key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { } | ||
267 | explicit key_value_pair_t(const KEY& k) : key(k) { } | ||
268 | inline bool operator < (const key_value_pair_t& o) const { | ||
269 | return strictly_order_type(key, o.key); | ||
270 | } | ||
271 | inline const KEY& getKey() const { | ||
272 | return key; | ||
273 | } | ||
274 | inline const VALUE& getValue() const { | ||
275 | return value; | ||
276 | } | ||
277 | }; | ||
278 | |||
279 | template <typename K, typename V> | ||
280 | struct trait_trivial_ctor< key_value_pair_t<K, V> > | ||
281 | { enum { value = aggregate_traits<K,V>::has_trivial_ctor }; }; | ||
282 | template <typename K, typename V> | ||
283 | struct trait_trivial_dtor< key_value_pair_t<K, V> > | ||
284 | { enum { value = aggregate_traits<K,V>::has_trivial_dtor }; }; | ||
285 | template <typename K, typename V> | ||
286 | struct trait_trivial_copy< key_value_pair_t<K, V> > | ||
287 | { enum { value = aggregate_traits<K,V>::has_trivial_copy }; }; | ||
288 | template <typename K, typename V> | ||
289 | struct trait_trivial_move< key_value_pair_t<K, V> > | ||
290 | { enum { value = aggregate_traits<K,V>::has_trivial_move }; }; | ||
291 | |||
292 | // --------------------------------------------------------------------------- | ||
293 | |||
294 | /* | ||
295 | * Hash codes. | ||
296 | */ | ||
297 | typedef uint32_t hash_t; | ||
298 | |||
299 | template <typename TKey> | ||
300 | hash_t hash_type(const TKey& key); | ||
301 | |||
302 | /* Built-in hash code specializations */ | ||
303 | #define ANDROID_INT32_HASH(T) \ | ||
304 | template <> inline hash_t hash_type(const T& value) { return hash_t(value); } | ||
305 | #define ANDROID_INT64_HASH(T) \ | ||
306 | template <> inline hash_t hash_type(const T& value) { \ | ||
307 | return hash_t((value >> 32) ^ value); } | ||
308 | #define ANDROID_REINTERPRET_HASH(T, R) \ | ||
309 | template <> inline hash_t hash_type(const T& value) { \ | ||
310 | R newValue; \ | ||
311 | static_assert(sizeof(newValue) == sizeof(value), "size mismatch"); \ | ||
312 | memcpy(&newValue, &value, sizeof(newValue)); \ | ||
313 | return hash_type(newValue); \ | ||
314 | } | ||
315 | |||
316 | ANDROID_INT32_HASH(bool) | ||
317 | ANDROID_INT32_HASH(int8_t) | ||
318 | ANDROID_INT32_HASH(uint8_t) | ||
319 | ANDROID_INT32_HASH(int16_t) | ||
320 | ANDROID_INT32_HASH(uint16_t) | ||
321 | ANDROID_INT32_HASH(int32_t) | ||
322 | ANDROID_INT32_HASH(uint32_t) | ||
323 | ANDROID_INT64_HASH(int64_t) | ||
324 | ANDROID_INT64_HASH(uint64_t) | ||
325 | ANDROID_REINTERPRET_HASH(float, uint32_t) | ||
326 | ANDROID_REINTERPRET_HASH(double, uint64_t) | ||
327 | |||
328 | template <typename T> inline hash_t hash_type(T* const & value) { | ||
329 | return hash_type(uintptr_t(value)); | ||
330 | } | ||
331 | |||
332 | }; // namespace android | ||
333 | |||
334 | // --------------------------------------------------------------------------- | ||
335 | |||
336 | #endif // ANDROID_TYPE_HELPERS_H | ||