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