Flutter Engine
TypeHelpers.h
Go to the documentation of this file.
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 <sys/types.h>
21 
22 #include <cstdint>
23 #include <cstring>
24 #include <new>
25 #include <type_traits>
26 
27 // ---------------------------------------------------------------------------
28 
29 namespace android {
30 
31 /*
32  * Types traits
33  */
34 
35 template <typename T>
37  enum { value = false };
38 };
39 template <typename T>
41  enum { value = false };
42 };
43 template <typename T>
45  enum { value = false };
46 };
47 template <typename T>
49  enum { value = false };
50 };
51 template <typename T>
52 struct trait_pointer {
53  enum { value = false };
54 };
55 template <typename T>
56 struct trait_pointer<T*> {
57  enum { value = true };
58 };
59 
60 template <typename TYPE>
61 struct traits {
62  enum {
63  // whether this type is a pointer
65  // whether this type's constructor is a no-op
66  has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value,
67  // whether this type's destructor is a no-op
68  has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value,
69  // whether this type type can be copy-constructed with memcpy
70  has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value,
71  // whether this type can be moved with memmove
72  has_trivial_move = is_pointer || trait_trivial_move<TYPE>::value
73  };
74 };
75 
76 template <typename T, typename U>
78  enum {
79  is_pointer = false,
80  has_trivial_ctor =
82  has_trivial_dtor =
84  has_trivial_copy =
86  has_trivial_move =
88  };
89 };
90 
91 #define ANDROID_TRIVIAL_CTOR_TRAIT(T) \
92  template <> \
93  struct trait_trivial_ctor<T> { \
94  enum { value = true }; \
95  };
96 
97 #define ANDROID_TRIVIAL_DTOR_TRAIT(T) \
98  template <> \
99  struct trait_trivial_dtor<T> { \
100  enum { value = true }; \
101  };
102 
103 #define ANDROID_TRIVIAL_COPY_TRAIT(T) \
104  template <> \
105  struct trait_trivial_copy<T> { \
106  enum { value = true }; \
107  };
108 
109 #define ANDROID_TRIVIAL_MOVE_TRAIT(T) \
110  template <> \
111  struct trait_trivial_move<T> { \
112  enum { value = true }; \
113  };
114 
115 #define ANDROID_BASIC_TYPES_TRAITS(T) \
116  ANDROID_TRIVIAL_CTOR_TRAIT(T) \
117  ANDROID_TRIVIAL_DTOR_TRAIT(T) \
118  ANDROID_TRIVIAL_COPY_TRAIT(T) \
119  ANDROID_TRIVIAL_MOVE_TRAIT(T)
120 
121 // ---------------------------------------------------------------------------
122 
123 /*
124  * basic types traits
125  */
126 
130 ANDROID_BASIC_TYPES_TRAITS(unsigned char)
132 ANDROID_BASIC_TYPES_TRAITS(unsigned short)
134 ANDROID_BASIC_TYPES_TRAITS(unsigned int)
136 ANDROID_BASIC_TYPES_TRAITS(unsigned long)
138 ANDROID_BASIC_TYPES_TRAITS(unsigned long long)
141 
142 // ---------------------------------------------------------------------------
143 
144 /*
145  * compare and order types
146  */
147 
148 template <typename TYPE>
149 inline int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
150  return (lhs < rhs) ? 1 : 0;
151 }
152 
153 template <typename TYPE>
154 inline int compare_type(const TYPE& lhs, const TYPE& rhs) {
155  return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
156 }
157 
158 /*
159  * create, destroy, copy and move types...
160  */
161 
162 template <typename TYPE>
163 inline void construct_type(TYPE* p, size_t n) {
165  while (n > 0) {
166  n--;
167  new (p++) TYPE;
168  }
169  }
170 }
171 
172 template <typename TYPE>
173 inline void destroy_type(TYPE* p, size_t n) {
175  while (n > 0) {
176  n--;
177  p->~TYPE();
178  p++;
179  }
180  }
181 }
182 
183 template <typename TYPE>
184 typename std::enable_if<traits<TYPE>::has_trivial_copy>::type inline copy_type(
185  TYPE* d,
186  const TYPE* s,
187  size_t n) {
188  memcpy(d, s, n * sizeof(TYPE));
189 }
190 
191 template <typename TYPE>
192 typename std::enable_if<!traits<TYPE>::has_trivial_copy>::type inline copy_type(
193  TYPE* d,
194  const TYPE* s,
195  size_t n) {
196  while (n > 0) {
197  n--;
198  new (d) TYPE(*s);
199  d++, s++;
200  }
201 }
202 
203 template <typename TYPE>
204 inline void splat_type(TYPE* where, const TYPE* what, size_t n) {
206  while (n > 0) {
207  n--;
208  new (where) TYPE(*what);
209  where++;
210  }
211  } else {
212  while (n > 0) {
213  n--;
214  *where++ = *what;
215  }
216  }
217 }
218 
219 template <typename TYPE>
221  : public std::integral_constant<bool,
222  (traits<TYPE>::has_trivial_dtor &&
223  traits<TYPE>::has_trivial_copy) ||
224  traits<TYPE>::has_trivial_move> {};
225 
226 template <typename TYPE>
228  type inline move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
229  memmove(d, s, n * sizeof(TYPE));
230 }
231 
232 template <typename TYPE>
234  type inline move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
235  d += n;
236  s += n;
237  while (n > 0) {
238  n--;
239  --d, --s;
241  new (d) TYPE(*s);
242  } else {
243  *d = *s;
244  }
246  s->~TYPE();
247  }
248  }
249 }
250 
251 template <typename TYPE>
253  type inline move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
254  memmove(d, s, n * sizeof(TYPE));
255 }
256 
257 template <typename TYPE>
259  type inline move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
260  while (n > 0) {
261  n--;
263  new (d) TYPE(*s);
264  } else {
265  *d = *s;
266  }
268  s->~TYPE();
269  }
270  d++, s++;
271  }
272 }
273 
274 // ---------------------------------------------------------------------------
275 
276 /*
277  * a key/value pair
278  */
279 
280 template <typename KEY, typename VALUE>
282  typedef KEY key_t;
283  typedef VALUE value_t;
284 
285  KEY key;
286  VALUE value;
288  key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) {}
290  key = o.key;
291  value = o.value;
292  return *this;
293  }
294  key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) {}
295  explicit key_value_pair_t(const KEY& k) : key(k) {}
296  inline bool operator<(const key_value_pair_t& o) const {
297  return strictly_order_type(key, o.key);
298  }
299  inline const KEY& getKey() const { return key; }
300  inline const VALUE& getValue() const { return value; }
301 };
302 
303 template <typename K, typename V>
306 };
307 template <typename K, typename V>
310 };
311 template <typename K, typename V>
314 };
315 template <typename K, typename V>
318 };
319 
320 // ---------------------------------------------------------------------------
321 
322 /*
323  * Hash codes.
324  */
325 typedef uint32_t hash_t;
326 
327 template <typename TKey>
328 hash_t hash_type(const TKey& key);
329 
330 /* Built-in hash code specializations */
331 #define ANDROID_INT32_HASH(T) \
332  template <> \
333  inline hash_t hash_type(const T& value) { \
334  return hash_t(value); \
335  }
336 #define ANDROID_INT64_HASH(T) \
337  template <> \
338  inline hash_t hash_type(const T& value) { \
339  return hash_t((value >> 32) ^ value); \
340  }
341 #define ANDROID_REINTERPRET_HASH(T, R) \
342  template <> \
343  inline hash_t hash_type(const T& value) { \
344  R newValue; \
345  static_assert(sizeof(newValue) == sizeof(value), "size mismatch"); \
346  memcpy(&newValue, &value, sizeof(newValue)); \
347  return hash_type(newValue); \
348  }
349 
350 ANDROID_INT32_HASH(bool)
351 ANDROID_INT32_HASH(int8_t)
352 ANDROID_INT32_HASH(uint8_t)
353 ANDROID_INT32_HASH(int16_t)
354 ANDROID_INT32_HASH(uint16_t)
355 ANDROID_INT32_HASH(int32_t)
356 ANDROID_INT32_HASH(uint32_t)
357 ANDROID_INT64_HASH(int64_t)
358 ANDROID_INT64_HASH(uint64_t)
359 ANDROID_REINTERPRET_HASH(float, uint32_t)
360 ANDROID_REINTERPRET_HASH(double, uint64_t)
361 
362 template <typename T>
363 inline hash_t hash_type(T* const& value) {
364  return hash_type(uintptr_t(value));
365 }
366 
367 }; // namespace android
368 
369 // ---------------------------------------------------------------------------
370 
371 #endif // ANDROID_TYPE_HELPERS_H
#define ANDROID_INT64_HASH(T)
Definition: TypeHelpers.h:336
key_value_pair_t(const key_value_pair_t &o)
Definition: TypeHelpers.h:288
std::enable_if< traits< TYPE >::has_trivial_copy >::type copy_type(TYPE *d, const TYPE *s, size_t n)
Definition: TypeHelpers.h:184
uint32_t hash_t
Definition: TypeHelpers.h:325
void construct_type(TYPE *p, size_t n)
Definition: TypeHelpers.h:163
const KEY & getKey() const
Definition: TypeHelpers.h:299
std::enable_if< use_trivial_move< TYPE >::value >::type move_forward_type(TYPE *d, const TYPE *s, size_t n=1)
Definition: TypeHelpers.h:228
key_value_pair_t(const KEY &k)
Definition: TypeHelpers.h:295
key_value_pair_t(const KEY &k, const VALUE &v)
Definition: TypeHelpers.h:294
#define ANDROID_INT32_HASH(T)
Definition: TypeHelpers.h:331
uint8_t value
#define ANDROID_REINTERPRET_HASH(T, R)
Definition: TypeHelpers.h:341
#define ANDROID_BASIC_TYPES_TRAITS(T)
Definition: TypeHelpers.h:115
std::enable_if< use_trivial_move< TYPE >::value >::type move_backward_type(TYPE *d, const TYPE *s, size_t n=1)
Definition: TypeHelpers.h:253
const VALUE & getValue() const
Definition: TypeHelpers.h:300
int compare_type(const TYPE &lhs, const TYPE &rhs)
Definition: TypeHelpers.h:154
int strictly_order_type(const TYPE &lhs, const TYPE &rhs)
Definition: TypeHelpers.h:149
void destroy_type(TYPE *p, size_t n)
Definition: TypeHelpers.h:173
bool operator<(const key_value_pair_t &o) const
Definition: TypeHelpers.h:296
hash_t hash_type(const TKey &key)
void splat_type(TYPE *where, const TYPE *what, size_t n)
Definition: TypeHelpers.h:204
key_value_pair_t & operator=(const key_value_pair_t &o)
Definition: TypeHelpers.h:289