1 /* 2 * TypeHelpers.h 3 * 4 * Copyright 2005 The Android Open Source Project 5 * 6 */ 7 8 #ifndef ANDROID_TYPE_HELPERS_H 9 #define ANDROID_TYPE_HELPERS_H 10 11 #include <new> 12 #include <stdint.h> 13 #include <string.h> 14 #include <sys/types.h> 15 16 // --------------------------------------------------------------------------- 17 18 namespace android { 19 20 /* 21 * Types traits 22 */ 23 24 template <typename T> struct trait_trivial_ctor { enum { value = false }; }; 25 template <typename T> struct trait_trivial_dtor { enum { value = false }; }; 26 template <typename T> struct trait_trivial_copy { enum { value = false }; }; 27 template <typename T> struct trait_trivial_assign{ enum { value = false }; }; 28 29 template <typename T> struct trait_pointer { enum { value = false }; }; 30 template <typename T> struct trait_pointer<T*> { enum { value = true }; }; 31 32 #define ANDROID_BASIC_TYPES_TRAITS( T ) \ 33 template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \ 34 template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \ 35 template<> struct trait_trivial_copy< T > { enum { value = true }; }; \ 36 template<> struct trait_trivial_assign< T >{ enum { value = true }; }; 37 38 #define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign ) \ 39 template<> struct trait_trivial_ctor< T > { enum { value = ctor }; }; \ 40 template<> struct trait_trivial_dtor< T > { enum { value = dtor }; }; \ 41 template<> struct trait_trivial_copy< T > { enum { value = copy }; }; \ 42 template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; 43 44 template <typename TYPE> 45 struct traits { 46 enum { 47 is_pointer = trait_pointer<TYPE>::value, 48 has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value, 49 has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value, 50 has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value, 51 has_trivial_assign = is_pointer || trait_trivial_assign<TYPE>::value 52 }; 53 }; 54 55 template <typename T, typename U> 56 struct aggregate_traits { 57 enum { 58 is_pointer = false, 59 has_trivial_ctor = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor, 60 has_trivial_dtor = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor, 61 has_trivial_copy = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy, 62 has_trivial_assign = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign 63 }; 64 }; 65 66 // --------------------------------------------------------------------------- 67 68 /* 69 * basic types traits 70 */ 71 72 ANDROID_BASIC_TYPES_TRAITS( void ); 73 ANDROID_BASIC_TYPES_TRAITS( bool ); 74 ANDROID_BASIC_TYPES_TRAITS( char ); 75 ANDROID_BASIC_TYPES_TRAITS( unsigned char ); 76 ANDROID_BASIC_TYPES_TRAITS( short ); 77 ANDROID_BASIC_TYPES_TRAITS( unsigned short ); 78 ANDROID_BASIC_TYPES_TRAITS( int ); 79 ANDROID_BASIC_TYPES_TRAITS( unsigned int ); 80 ANDROID_BASIC_TYPES_TRAITS( long ); 81 ANDROID_BASIC_TYPES_TRAITS( unsigned long ); 82 ANDROID_BASIC_TYPES_TRAITS( long long ); 83 ANDROID_BASIC_TYPES_TRAITS( unsigned long long ); 84 ANDROID_BASIC_TYPES_TRAITS( float ); 85 ANDROID_BASIC_TYPES_TRAITS( double ); 86 87 // --------------------------------------------------------------------------- 88 89 90 /* 91 * compare and order types 92 */ 93 94 template<typename TYPE> inline 95 int strictly_order_type(const TYPE& lhs, const TYPE& rhs) { 96 return (lhs < rhs) ? 1 : 0; 97 } 98 99 template<typename TYPE> inline 100 int compare_type(const TYPE& lhs, const TYPE& rhs) { 101 return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs); 102 } 103 104 /* 105 * create, destroy, copy and assign types... 106 */ 107 108 template<typename TYPE> inline 109 void construct_type(TYPE* p, size_t n) { 110 if (!traits<TYPE>::has_trivial_ctor) { 111 while (n--) { 112 new(p++) TYPE; 113 } 114 } 115 } 116 117 template<typename TYPE> inline 118 void destroy_type(TYPE* p, size_t n) { 119 if (!traits<TYPE>::has_trivial_dtor) { 120 while (n--) { 121 p->~TYPE(); 122 p++; 123 } 124 } 125 } 126 127 template<typename TYPE> inline 128 void copy_type(TYPE* d, const TYPE* s, size_t n) { 129 if (!traits<TYPE>::has_trivial_copy) { 130 while (n--) { 131 new(d) TYPE(*s); 132 d++, s++; 133 } 134 } else { 135 memcpy(d,s,n*sizeof(TYPE)); 136 } 137 } 138 139 template<typename TYPE> inline 140 void assign_type(TYPE* d, const TYPE* s, size_t n) { 141 if (!traits<TYPE>::has_trivial_assign) { 142 while (n--) { 143 *d++ = *s++; 144 } 145 } else { 146 memcpy(d,s,n*sizeof(TYPE)); 147 } 148 } 149 150 template<typename TYPE> inline 151 void splat_type(TYPE* where, const TYPE* what, size_t n) { 152 if (!traits<TYPE>::has_trivial_copy) { 153 while (n--) { 154 new(where) TYPE(*what); 155 where++; 156 } 157 } else { 158 while (n--) { 159 *where++ = *what; 160 } 161 } 162 } 163 164 template<typename TYPE> inline 165 void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { 166 if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) { 167 d += n; 168 s += n; 169 while (n--) { 170 --d, --s; 171 if (!traits<TYPE>::has_trivial_copy) { 172 new(d) TYPE(*s); 173 } else { 174 *d = *s; 175 } 176 if (!traits<TYPE>::has_trivial_dtor) { 177 s->~TYPE(); 178 } 179 } 180 } else { 181 memmove(d,s,n*sizeof(TYPE)); 182 } 183 } 184 185 template<typename TYPE> inline 186 void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { 187 if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) { 188 while (n--) { 189 if (!traits<TYPE>::has_trivial_copy) { 190 new(d) TYPE(*s); 191 } else { 192 *d = *s; 193 } 194 if (!traits<TYPE>::has_trivial_dtor) { 195 s->~TYPE(); 196 } 197 d++, s++; 198 } 199 } else { 200 memmove(d,s,n*sizeof(TYPE)); 201 } 202 } 203 // --------------------------------------------------------------------------- 204 205 /* 206 * a key/value pair 207 */ 208 209 template <typename KEY, typename VALUE> 210 struct key_value_pair_t { 211 KEY key; 212 VALUE value; 213 key_value_pair_t() { } 214 key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { } 215 key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { } 216 key_value_pair_t(const KEY& k) : key(k) { } 217 inline bool operator < (const key_value_pair_t& o) const { 218 return strictly_order_type(key, o.key); 219 } 220 }; 221 222 template<> 223 template <typename K, typename V> 224 struct trait_trivial_ctor< key_value_pair_t<K, V> > 225 { enum { value = aggregate_traits<K,V>::has_trivial_ctor }; }; 226 template<> 227 template <typename K, typename V> 228 struct trait_trivial_dtor< key_value_pair_t<K, V> > 229 { enum { value = aggregate_traits<K,V>::has_trivial_dtor }; }; 230 template<> 231 template <typename K, typename V> 232 struct trait_trivial_copy< key_value_pair_t<K, V> > 233 { enum { value = aggregate_traits<K,V>::has_trivial_copy }; }; 234 template<> 235 template <typename K, typename V> 236 struct trait_trivial_assign< key_value_pair_t<K, V> > 237 { enum { value = aggregate_traits<K,V>::has_trivial_assign};}; 238 239 // --------------------------------------------------------------------------- 240 241 }; // namespace android 242 243 // --------------------------------------------------------------------------- 244 245 #endif // ANDROID_TYPE_HELPERS_H 246