• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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