2
* Copyright (C) 2005 The Android Open Source Project
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
#ifndef ANDROID_TYPE_HELPERS_H
18
#define ANDROID_TYPE_HELPERS_H
23
#include <sys/types.h>
25
// ---------------------------------------------------------------------------
33
template <typename T> struct trait_trivial_ctor { enum { value = false }; };
34
template <typename T> struct trait_trivial_dtor { enum { value = false }; };
35
template <typename T> struct trait_trivial_copy { enum { value = false }; };
36
template <typename T> struct trait_trivial_move { enum { value = false }; };
37
template <typename T> struct trait_pointer { enum { value = false }; };
38
template <typename T> struct trait_pointer<T*> { enum { value = true }; };
40
template <typename TYPE>
43
// whether this type is a pointer
44
is_pointer = trait_pointer<TYPE>::value,
45
// whether this type's constructor is a no-op
46
has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value,
47
// whether this type's destructor is a no-op
48
has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value,
49
// whether this type type can be copy-constructed with memcpy
50
has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value,
51
// whether this type can be moved with memmove
52
has_trivial_move = is_pointer || trait_trivial_move<TYPE>::value
56
template <typename T, typename U>
57
struct aggregate_traits {
61
traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
63
traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
65
traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
67
traits<T>::has_trivial_move && traits<U>::has_trivial_move
71
#define ANDROID_BASIC_TYPES_TRAITS( T ) \
72
template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \
73
template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \
74
template<> struct trait_trivial_copy< T > { enum { value = true }; }; \
75
template<> struct trait_trivial_move< T > { enum { value = true }; };
77
// ---------------------------------------------------------------------------
83
ANDROID_BASIC_TYPES_TRAITS( void )
84
ANDROID_BASIC_TYPES_TRAITS( bool )
85
ANDROID_BASIC_TYPES_TRAITS( char )
86
ANDROID_BASIC_TYPES_TRAITS( unsigned char )
87
ANDROID_BASIC_TYPES_TRAITS( short )
88
ANDROID_BASIC_TYPES_TRAITS( unsigned short )
89
ANDROID_BASIC_TYPES_TRAITS( int )
90
ANDROID_BASIC_TYPES_TRAITS( unsigned int )
91
ANDROID_BASIC_TYPES_TRAITS( long )
92
ANDROID_BASIC_TYPES_TRAITS( unsigned long )
93
ANDROID_BASIC_TYPES_TRAITS( long long )
94
ANDROID_BASIC_TYPES_TRAITS( unsigned long long )
95
ANDROID_BASIC_TYPES_TRAITS( float )
96
ANDROID_BASIC_TYPES_TRAITS( double )
98
// ---------------------------------------------------------------------------
102
* compare and order types
105
template<typename TYPE> inline
106
int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
107
return (lhs < rhs) ? 1 : 0;
110
template<typename TYPE> inline
111
int compare_type(const TYPE& lhs, const TYPE& rhs) {
112
return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
116
* create, destroy, copy and move types...
119
template<typename TYPE> inline
120
void construct_type(TYPE* p, size_t n) {
121
if (!traits<TYPE>::has_trivial_ctor) {
128
template<typename TYPE> inline
129
void destroy_type(TYPE* p, size_t n) {
130
if (!traits<TYPE>::has_trivial_dtor) {
138
template<typename TYPE> inline
139
void copy_type(TYPE* d, const TYPE* s, size_t n) {
140
if (!traits<TYPE>::has_trivial_copy) {
146
memcpy(d,s,n*sizeof(TYPE));
150
template<typename TYPE> inline
151
void splat_type(TYPE* where, const TYPE* what, size_t n) {
152
if (!traits<TYPE>::has_trivial_copy) {
154
new(where) TYPE(*what);
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_dtor && traits<TYPE>::has_trivial_copy)
167
|| traits<TYPE>::has_trivial_move)
169
memmove(d,s,n*sizeof(TYPE));
175
if (!traits<TYPE>::has_trivial_copy) {
180
if (!traits<TYPE>::has_trivial_dtor) {
187
template<typename TYPE> inline
188
void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
189
if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
190
|| traits<TYPE>::has_trivial_move)
192
memmove(d,s,n*sizeof(TYPE));
195
if (!traits<TYPE>::has_trivial_copy) {
200
if (!traits<TYPE>::has_trivial_dtor) {
208
// ---------------------------------------------------------------------------
214
template <typename KEY, typename VALUE>
215
struct key_value_pair_t {
218
key_value_pair_t() { }
219
key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
220
key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { }
221
key_value_pair_t(const KEY& k) : key(k) { }
222
inline bool operator < (const key_value_pair_t& o) const {
223
return strictly_order_type(key, o.key);
228
template <typename K, typename V>
229
struct trait_trivial_ctor< key_value_pair_t<K, V> >
230
{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
232
template <typename K, typename V>
233
struct trait_trivial_dtor< key_value_pair_t<K, V> >
234
{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
236
template <typename K, typename V>
237
struct trait_trivial_copy< key_value_pair_t<K, V> >
238
{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
240
template <typename K, typename V>
241
struct trait_trivial_move< key_value_pair_t<K, V> >
242
{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
244
// ---------------------------------------------------------------------------
246
}; // namespace android
248
// ---------------------------------------------------------------------------
250
#endif // ANDROID_TYPE_HELPERS_H