Line data Source code
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 stagefright {
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 0 : int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
119 0 : return (lhs < rhs) ? 1 : 0;
120 : }
121 :
122 : template<typename TYPE> inline
123 0 : int compare_type(const TYPE& lhs, const TYPE& rhs) {
124 0 : 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 0 : void construct_type(TYPE* p, size_t n) {
133 : if (!traits<TYPE>::has_trivial_ctor) {
134 0 : while (n--) {
135 0 : new(p++) TYPE;
136 : }
137 : }
138 0 : }
139 :
140 : template<typename TYPE> inline
141 702 : void destroy_type(TYPE* p, size_t n) {
142 : if (!traits<TYPE>::has_trivial_dtor) {
143 1383 : while (n--) {
144 681 : p->~TYPE();
145 681 : p++;
146 : }
147 : }
148 21 : }
149 :
150 : template<typename TYPE> inline
151 21 : void copy_type(TYPE* d, const TYPE* s, size_t n) {
152 : if (!traits<TYPE>::has_trivial_copy) {
153 1383 : while (n--) {
154 681 : new(d) TYPE(*s);
155 681 : d++, s++;
156 : }
157 : } else {
158 0 : memcpy(d,s,n*sizeof(TYPE));
159 : }
160 21 : }
161 :
162 : template<typename TYPE> inline
163 384 : void splat_type(TYPE* where, const TYPE* what, size_t n) {
164 : if (!traits<TYPE>::has_trivial_copy) {
165 1152 : while (n--) {
166 384 : new(where) TYPE(*what);
167 384 : where++;
168 : }
169 : } else {
170 0 : while (n--) {
171 0 : *where++ = *what;
172 : }
173 : }
174 384 : }
175 :
176 : template<typename TYPE> inline
177 0 : 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 0 : memmove(d,s,n*sizeof(TYPE));
182 : } else {
183 0 : d += n;
184 0 : s += n;
185 0 : while (n--) {
186 0 : --d, --s;
187 : if (!traits<TYPE>::has_trivial_copy) {
188 0 : new(d) TYPE(*s);
189 : } else {
190 : *d = *s;
191 : }
192 : if (!traits<TYPE>::has_trivial_dtor) {
193 0 : s->~TYPE();
194 : }
195 : }
196 : }
197 0 : }
198 :
199 : template<typename TYPE> inline
200 0 : 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 0 : memmove((void*)d,(void*)s,n*sizeof(TYPE));
205 : } else {
206 0 : while (n--) {
207 : if (!traits<TYPE>::has_trivial_copy) {
208 0 : new(d) TYPE(*s);
209 : } else {
210 : *d = *s;
211 : }
212 : if (!traits<TYPE>::has_trivial_dtor) {
213 0 : s->~TYPE();
214 : }
215 0 : d++, s++;
216 : }
217 : }
218 0 : }
219 :
220 : // ---------------------------------------------------------------------------
221 :
222 : /*
223 : * a key/value pair
224 : */
225 :
226 : template <typename KEY, typename VALUE>
227 0 : struct key_value_pair_t {
228 : typedef KEY key_t;
229 : typedef VALUE value_t;
230 :
231 : KEY key;
232 : VALUE value;
233 0 : key_value_pair_t() { }
234 0 : key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
235 0 : key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { }
236 0 : key_value_pair_t(const KEY& k) : key(k) { }
237 0 : inline bool operator < (const key_value_pair_t& o) const {
238 0 : 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(T* const & value) {
295 : return hash_type(uintptr_t(value));
296 : }
297 :
298 : }; // namespace stagefright
299 :
300 : // ---------------------------------------------------------------------------
301 :
302 : #endif // ANDROID_TYPE_HELPERS_H
|