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