~mir-team/mir/in-process-egl+input-conglomeration

« back to all changes in this revision

Viewing changes to 3rd_party/android-input/android_pristine/frameworks/native/include/utils/TypeHelpers.h

Merged trunk and fixed issues

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 <stdint.h>
22
 
#include <string.h>
23
 
#include <sys/types.h>
24
 
 
25
 
// ---------------------------------------------------------------------------
26
 
 
27
 
namespace android {
28
 
 
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
 
 * compare and order types
115
 
 */
116
 
 
117
 
template<typename TYPE> inline
118
 
int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
119
 
    return (lhs < rhs) ? 1 : 0;
120
 
}
121
 
 
122
 
template<typename TYPE> inline
123
 
int compare_type(const TYPE& lhs, const TYPE& rhs) {
124
 
    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
125
 
}
126
 
 
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
 
// ---------------------------------------------------------------------------
221
 
 
222
 
/*
223
 
 * a key/value pair
224
 
 */
225
 
 
226
 
template <typename KEY, typename VALUE>
227
 
struct key_value_pair_t {
228
 
    typedef KEY key_t;
229
 
    typedef VALUE value_t;
230
 
 
231
 
    KEY     key;
232
 
    VALUE   value;
233
 
    key_value_pair_t() { }
234
 
    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
235
 
    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
236
 
    key_value_pair_t(const KEY& k) : key(k) { }
237
 
    inline bool operator < (const key_value_pair_t& o) const {
238
 
        return strictly_order_type(key, o.key);
239
 
    }
240
 
    inline const KEY& getKey() const {
241
 
        return key;
242
 
    }
243
 
    inline const VALUE& getValue() const {
244
 
        return value;
245
 
    }
246
 
};
247
 
 
248
 
template <typename K, typename V>
249
 
struct trait_trivial_ctor< key_value_pair_t<K, V> >
250
 
{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
251
 
template <typename K, typename V>
252
 
struct trait_trivial_dtor< key_value_pair_t<K, V> >
253
 
{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
254
 
template <typename K, typename V>
255
 
struct trait_trivial_copy< key_value_pair_t<K, V> >
256
 
{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
257
 
template <typename K, typename V>
258
 
struct trait_trivial_move< key_value_pair_t<K, V> >
259
 
{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
260
 
 
261
 
// ---------------------------------------------------------------------------
262
 
 
263
 
/*
264
 
 * Hash codes.
265
 
 */
266
 
typedef uint32_t hash_t;
267
 
 
268
 
template <typename TKey>
269
 
hash_t hash_type(const TKey& key);
270
 
 
271
 
/* Built-in hash code specializations.
272
 
 * Assumes pointers are 32bit. */
273
 
#define ANDROID_INT32_HASH(T) \
274
 
        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
275
 
#define ANDROID_INT64_HASH(T) \
276
 
        template <> inline hash_t hash_type(const T& value) { \
277
 
                return hash_t((value >> 32) ^ value); }
278
 
#define ANDROID_REINTERPRET_HASH(T, R) \
279
 
        template <> inline hash_t hash_type(const T& value) { \
280
 
                return hash_type(*reinterpret_cast<const R*>(&value)); }
281
 
 
282
 
ANDROID_INT32_HASH(bool)
283
 
ANDROID_INT32_HASH(int8_t)
284
 
ANDROID_INT32_HASH(uint8_t)
285
 
ANDROID_INT32_HASH(int16_t)
286
 
ANDROID_INT32_HASH(uint16_t)
287
 
ANDROID_INT32_HASH(int32_t)
288
 
ANDROID_INT32_HASH(uint32_t)
289
 
ANDROID_INT64_HASH(int64_t)
290
 
ANDROID_INT64_HASH(uint64_t)
291
 
ANDROID_REINTERPRET_HASH(float, uint32_t)
292
 
ANDROID_REINTERPRET_HASH(double, uint64_t)
293
 
 
294
 
template <typename T> inline hash_t hash_type(const T*& value) {
295
 
    return hash_type(uintptr_t(value));
296
 
}
297
 
 
298
 
}; // namespace android
299
 
 
300
 
// ---------------------------------------------------------------------------
301
 
 
302
 
#endif // ANDROID_TYPE_HELPERS_H