~vanvugt/mir/earlier-release

« back to all changes in this revision

Viewing changes to 3rd_party/android-deps/utils/TypeHelpers.h

  • Committer: Daniel van Vugt
  • Date: 2015-08-18 01:35:15 UTC
  • mfrom: (2798.1.51 trunk)
  • Revision ID: daniel.van.vugt@canonical.com-20150818013515-tjwa9ochp2rwpz7h
Merge latest trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
namespace android {
28
28
 
29
29
/*
30
 
 * Types traits
31
 
 */
32
 
 
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 }; };
39
 
 
40
 
template <typename TYPE>
41
 
struct traits {
42
 
    enum {
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
53
 
    };
54
 
};
55
 
 
56
 
template <typename T, typename U>
57
 
struct aggregate_traits {
58
 
    enum {
59
 
        is_pointer          = false,
60
 
        has_trivial_ctor    = 
61
 
            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
62
 
        has_trivial_dtor    = 
63
 
            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
64
 
        has_trivial_copy    = 
65
 
            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
66
 
        has_trivial_move    = 
67
 
            traits<T>::has_trivial_move && traits<U>::has_trivial_move
68
 
    };
69
 
};
70
 
 
71
 
#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
72
 
    template<> struct trait_trivial_ctor< T >   { enum { value = true }; };
73
 
 
74
 
#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
75
 
    template<> struct trait_trivial_dtor< T >   { enum { value = true }; };
76
 
 
77
 
#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
78
 
    template<> struct trait_trivial_copy< T >   { enum { value = true }; };
79
 
 
80
 
#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
81
 
    template<> struct trait_trivial_move< T >   { enum { value = true }; };
82
 
 
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 )
88
 
 
89
 
// ---------------------------------------------------------------------------
90
 
 
91
 
/*
92
 
 * basic types traits
93
 
 */
94
 
 
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 )
109
 
 
110
 
// ---------------------------------------------------------------------------
111
 
 
112
 
 
113
 
/*
114
30
 * compare and order types
115
31
 */
116
32
 
124
40
    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
125
41
}
126
42
 
127
 
/*
128
 
 * create, destroy, copy and move types...
129
 
 */
130
 
 
131
 
template<typename TYPE> inline
132
 
void construct_type(TYPE* p, size_t n) {
133
 
    if (!traits<TYPE>::has_trivial_ctor) {
134
 
        while (n--) {
135
 
            new(p++) TYPE;
136
 
        }
137
 
    }
138
 
}
139
 
 
140
 
template<typename TYPE> inline
141
 
void destroy_type(TYPE* p, size_t n) {
142
 
    if (!traits<TYPE>::has_trivial_dtor) {
143
 
        while (n--) {
144
 
            p->~TYPE();
145
 
            p++;
146
 
        }
147
 
    }
148
 
}
149
 
 
150
 
template<typename TYPE> inline
151
 
void copy_type(TYPE* d, const TYPE* s, size_t n) {
152
 
    if (!traits<TYPE>::has_trivial_copy) {
153
 
        while (n--) {
154
 
            new(d) TYPE(*s);
155
 
            d++, s++;
156
 
        }
157
 
    } else {
158
 
        memcpy(d,s,n*sizeof(TYPE));
159
 
    }
160
 
}
161
 
 
162
 
template<typename TYPE> inline
163
 
void splat_type(TYPE* where, const TYPE* what, size_t n) {
164
 
    if (!traits<TYPE>::has_trivial_copy) {
165
 
        while (n--) {
166
 
            new(where) TYPE(*what);
167
 
            where++;
168
 
        }
169
 
    } else {
170
 
        while (n--) {
171
 
            *where++ = *what;
172
 
        }
173
 
    }
174
 
}
175
 
 
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) 
180
 
    {
181
 
        memmove(d,s,n*sizeof(TYPE));
182
 
    } else {
183
 
        d += n;
184
 
        s += n;
185
 
        while (n--) {
186
 
            --d, --s;
187
 
            if (!traits<TYPE>::has_trivial_copy) {
188
 
                new(d) TYPE(*s);
189
 
            } else {
190
 
                *d = *s;   
191
 
            }
192
 
            if (!traits<TYPE>::has_trivial_dtor) {
193
 
                s->~TYPE();
194
 
            }
195
 
        }
196
 
    }
197
 
}
198
 
 
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) 
203
 
    {
204
 
        memmove(d,s,n*sizeof(TYPE));
205
 
    } else {
206
 
        while (n--) {
207
 
            if (!traits<TYPE>::has_trivial_copy) {
208
 
                new(d) TYPE(*s);
209
 
            } else {
210
 
                *d = *s;   
211
 
            }
212
 
            if (!traits<TYPE>::has_trivial_dtor) {
213
 
                s->~TYPE();
214
 
            }
215
 
            d++, s++;
216
 
        }
217
 
    }
218
 
}
219
 
 
220
43
// ---------------------------------------------------------------------------
221
44
 
222
45
/*
248
71
    }
249
72
};
250
73
 
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 }; };
263
 
 
264
 
// ---------------------------------------------------------------------------
265
 
 
266
 
/*
267
 
 * Hash codes.
268
 
 */
269
 
typedef uint32_t hash_t;
270
 
 
271
 
template <typename TKey>
272
 
hash_t hash_type(const TKey& key);
273
 
 
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)); }
284
 
 
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)
296
 
 
297
 
template <typename T> inline hash_t hash_type(const T*& value) {
298
 
    return hash_type(uintptr_t(value));
299
 
}
300
74
 
301
75
} // namespace android
302
76