2
* Copyright (C) 2005 The Android Open Source Project
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
#ifndef ANDROID_TYPE_HELPERS_H
18
#define ANDROID_TYPE_HELPERS_H
23
#include <sys/types.h>
25
// ---------------------------------------------------------------------------
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
* compare and order types
117
template<typename TYPE> inline
118
int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
119
return (lhs < rhs) ? 1 : 0;
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);
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
// ---------------------------------------------------------------------------
226
template <typename KEY, typename VALUE>
227
struct key_value_pair_t {
229
typedef VALUE value_t;
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);
240
inline const KEY& getKey() const {
243
inline const VALUE& getValue() const {
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 }; };
261
// ---------------------------------------------------------------------------
266
typedef uint32_t hash_t;
268
template <typename TKey>
269
hash_t hash_type(const TKey& key);
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)); }
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)
294
template <typename T> inline hash_t hash_type(const T*& value) {
295
return hash_type(uintptr_t(value));
298
}; // namespace android
300
// ---------------------------------------------------------------------------
302
#endif // ANDROID_TYPE_HELPERS_H