27
27
namespace android {
33
template <typename T> struct trait_trivial_ctor { enum { value = false }; };
34
template <typename T> struct trait_trivial_dtor { enum { value = false }; };
35
template <typename T> struct trait_trivial_copy { enum { value = false }; };
36
template <typename T> struct trait_trivial_move { enum { value = false }; };
37
template <typename T> struct trait_pointer { enum { value = false }; };
38
template <typename T> struct trait_pointer<T*> { enum { value = true }; };
40
template <typename TYPE>
43
// whether this type is a pointer
44
is_pointer = trait_pointer<TYPE>::value,
45
// whether this type's constructor is a no-op
46
has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value,
47
// whether this type's destructor is a no-op
48
has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value,
49
// whether this type type can be copy-constructed with memcpy
50
has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value,
51
// whether this type can be moved with memmove
52
has_trivial_move = is_pointer || trait_trivial_move<TYPE>::value
56
template <typename T, typename U>
57
struct aggregate_traits {
61
traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
63
traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
65
traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
67
traits<T>::has_trivial_move && traits<U>::has_trivial_move
71
#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
72
template<> struct trait_trivial_ctor< T > { enum { value = true }; };
74
#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
75
template<> struct trait_trivial_dtor< T > { enum { value = true }; };
77
#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
78
template<> struct trait_trivial_copy< T > { enum { value = true }; };
80
#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
81
template<> struct trait_trivial_move< T > { enum { value = true }; };
83
#define ANDROID_BASIC_TYPES_TRAITS( T ) \
84
ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
85
ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
86
ANDROID_TRIVIAL_COPY_TRAIT( T ) \
87
ANDROID_TRIVIAL_MOVE_TRAIT( T )
89
// ---------------------------------------------------------------------------
95
ANDROID_BASIC_TYPES_TRAITS( void )
96
ANDROID_BASIC_TYPES_TRAITS( bool )
97
ANDROID_BASIC_TYPES_TRAITS( char )
98
ANDROID_BASIC_TYPES_TRAITS( unsigned char )
99
ANDROID_BASIC_TYPES_TRAITS( short )
100
ANDROID_BASIC_TYPES_TRAITS( unsigned short )
101
ANDROID_BASIC_TYPES_TRAITS( int )
102
ANDROID_BASIC_TYPES_TRAITS( unsigned int )
103
ANDROID_BASIC_TYPES_TRAITS( long )
104
ANDROID_BASIC_TYPES_TRAITS( unsigned long )
105
ANDROID_BASIC_TYPES_TRAITS( long long )
106
ANDROID_BASIC_TYPES_TRAITS( unsigned long long )
107
ANDROID_BASIC_TYPES_TRAITS( float )
108
ANDROID_BASIC_TYPES_TRAITS( double )
110
// ---------------------------------------------------------------------------
114
30
* compare and order types
124
40
return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
128
* create, destroy, copy and move types...
131
template<typename TYPE> inline
132
void construct_type(TYPE* p, size_t n) {
133
if (!traits<TYPE>::has_trivial_ctor) {
140
template<typename TYPE> inline
141
void destroy_type(TYPE* p, size_t n) {
142
if (!traits<TYPE>::has_trivial_dtor) {
150
template<typename TYPE> inline
151
void copy_type(TYPE* d, const TYPE* s, size_t n) {
152
if (!traits<TYPE>::has_trivial_copy) {
158
memcpy(d,s,n*sizeof(TYPE));
162
template<typename TYPE> inline
163
void splat_type(TYPE* where, const TYPE* what, size_t n) {
164
if (!traits<TYPE>::has_trivial_copy) {
166
new(where) TYPE(*what);
176
template<typename TYPE> inline
177
void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
178
if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
179
|| traits<TYPE>::has_trivial_move)
181
memmove(d,s,n*sizeof(TYPE));
187
if (!traits<TYPE>::has_trivial_copy) {
192
if (!traits<TYPE>::has_trivial_dtor) {
199
template<typename TYPE> inline
200
void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
201
if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
202
|| traits<TYPE>::has_trivial_move)
204
memmove(d,s,n*sizeof(TYPE));
207
if (!traits<TYPE>::has_trivial_copy) {
212
if (!traits<TYPE>::has_trivial_dtor) {
220
43
// ---------------------------------------------------------------------------
251
template <typename K, typename V>
252
struct trait_trivial_ctor< key_value_pair_t<K, V> >
253
{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
254
template <typename K, typename V>
255
struct trait_trivial_dtor< key_value_pair_t<K, V> >
256
{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
257
template <typename K, typename V>
258
struct trait_trivial_copy< key_value_pair_t<K, V> >
259
{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
260
template <typename K, typename V>
261
struct trait_trivial_move< key_value_pair_t<K, V> >
262
{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
264
// ---------------------------------------------------------------------------
269
typedef uint32_t hash_t;
271
template <typename TKey>
272
hash_t hash_type(const TKey& key);
274
/* Built-in hash code specializations.
275
* Assumes pointers are 32bit. */
276
#define ANDROID_INT32_HASH(T) \
277
template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
278
#define ANDROID_INT64_HASH(T) \
279
template <> inline hash_t hash_type(const T& value) { \
280
return hash_t((value >> 32) ^ value); }
281
#define ANDROID_REINTERPRET_HASH(T, R) \
282
template <> inline hash_t hash_type(const T& value) { \
283
return hash_type(*reinterpret_cast<const R*>(&value)); }
285
ANDROID_INT32_HASH(bool)
286
ANDROID_INT32_HASH(int8_t)
287
ANDROID_INT32_HASH(uint8_t)
288
ANDROID_INT32_HASH(int16_t)
289
ANDROID_INT32_HASH(uint16_t)
290
ANDROID_INT32_HASH(int32_t)
291
ANDROID_INT32_HASH(uint32_t)
292
ANDROID_INT64_HASH(int64_t)
293
ANDROID_INT64_HASH(uint64_t)
294
ANDROID_REINTERPRET_HASH(float, uint32_t)
295
ANDROID_REINTERPRET_HASH(double, uint64_t)
297
template <typename T> inline hash_t hash_type(const T*& value) {
298
return hash_type(uintptr_t(value));
301
75
} // namespace android