blob: 7abff072f75524dd1a4c4fc1e093bdd7ad50f161 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
Mathias Agopian9857d992013-04-01 15:17:55 -07002 * Copyright 2005 The Android Open Source Project
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08003 *
Mathias Agopian9857d992013-04-01 15:17:55 -07004 * 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.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080015 */
16
Mathias Agopian9857d992013-04-01 15:17:55 -070017#ifndef ANDROID_PIXELFLINGER_TYPE_HELPERS_H
18#define ANDROID_PIXELFLINGER_TYPE_HELPERS_H
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080019
20#include <new>
21#include <stdint.h>
22#include <string.h>
23#include <sys/types.h>
24
25// ---------------------------------------------------------------------------
26
27namespace android {
Mathias Agopian9857d992013-04-01 15:17:55 -070028namespace tinyutils {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080029
30/*
31 * Types traits
32 */
33
34template <typename T> struct trait_trivial_ctor { enum { value = false }; };
35template <typename T> struct trait_trivial_dtor { enum { value = false }; };
36template <typename T> struct trait_trivial_copy { enum { value = false }; };
37template <typename T> struct trait_trivial_assign{ enum { value = false }; };
38
39template <typename T> struct trait_pointer { enum { value = false }; };
40template <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
54template <typename TYPE>
55struct 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
65template <typename T, typename U>
66struct 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
82ANDROID_BASIC_TYPES_TRAITS( void );
83ANDROID_BASIC_TYPES_TRAITS( bool );
84ANDROID_BASIC_TYPES_TRAITS( char );
85ANDROID_BASIC_TYPES_TRAITS( unsigned char );
86ANDROID_BASIC_TYPES_TRAITS( short );
87ANDROID_BASIC_TYPES_TRAITS( unsigned short );
88ANDROID_BASIC_TYPES_TRAITS( int );
89ANDROID_BASIC_TYPES_TRAITS( unsigned int );
90ANDROID_BASIC_TYPES_TRAITS( long );
91ANDROID_BASIC_TYPES_TRAITS( unsigned long );
92ANDROID_BASIC_TYPES_TRAITS( long long );
93ANDROID_BASIC_TYPES_TRAITS( unsigned long long );
94ANDROID_BASIC_TYPES_TRAITS( float );
95ANDROID_BASIC_TYPES_TRAITS( double );
96
97// ---------------------------------------------------------------------------
98
99
100/*
101 * compare and order types
102 */
103
104template<typename TYPE> inline
105int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
106 return (lhs < rhs) ? 1 : 0;
107}
108
109template<typename TYPE> inline
110int 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
118template<typename TYPE> inline
119void 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
127template<typename TYPE> inline
128void 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
137template<typename TYPE> inline
138void 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
149template<typename TYPE> inline
150void 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
160template<typename TYPE> inline
161void 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
174template<typename TYPE> inline
175void 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
195template<typename TYPE> inline
196void 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
219template <typename KEY, typename VALUE>
220struct 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
232template<>
233template <typename K, typename V>
234struct trait_trivial_ctor< key_value_pair_t<K, V> >
235{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
236template<>
237template <typename K, typename V>
238struct trait_trivial_dtor< key_value_pair_t<K, V> >
239{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
240template<>
241template <typename K, typename V>
242struct trait_trivial_copy< key_value_pair_t<K, V> >
243{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
244template<>
245template <typename K, typename V>
246struct trait_trivial_assign< key_value_pair_t<K, V> >
247{ enum { value = aggregate_traits<K,V>::has_trivial_assign};};
248
249// ---------------------------------------------------------------------------
250
Mathias Agopian9857d992013-04-01 15:17:55 -0700251} // namespace tinyutils
252} // namespace android
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800253
254// ---------------------------------------------------------------------------
255
Mathias Agopian9857d992013-04-01 15:17:55 -0700256#endif // ANDROID_PIXELFLINGER_TYPE_HELPERS_H