blob: c04c37fa986a24a9e3e0a65ee767b5a808b2ffac [file] [log] [blame]
The Android Open Source Projectcbb10112009-03-03 19:31:44 -08001/*
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