1cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
2cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
3cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
4cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * you may not use this file except in compliance with the License.
6cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * You may obtain a copy of the License at
7cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
8cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *
10cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * See the License for the specific language governing permissions and
14cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * limitations under the License.
15cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
16cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
17cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#ifndef ANDROID_TYPE_HELPERS_H
18cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define ANDROID_TYPE_HELPERS_H
19cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
20cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <new>
21cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <stdint.h>
22cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <string.h>
23cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <sys/types.h>
24cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
25cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
26cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
27cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectnamespace android {
28cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
29cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
30cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Types traits
31cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
32a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
33a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_trivial_ctor { enum { value = false }; };
34a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_trivial_dtor { enum { value = false }; };
35a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_trivial_copy { enum { value = false }; };
36a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_trivial_move { enum { value = false }; };
37a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_pointer      { enum { value = false }; };
38a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_pointer<T*>  { enum { value = true }; };
39a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
40cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename TYPE>
41cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct traits {
42cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    enum {
43a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type is a pointer
44cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        is_pointer          = trait_pointer<TYPE>::value,
45a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type's constructor is a no-op
46cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
47a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type's destructor is a no-op
48cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
49a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type type can be copy-constructed with memcpy
50cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
51a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type can be moved with memmove
52a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
53cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    };
54cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project};
55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
56cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename T, typename U>
57cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct aggregate_traits {
58cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    enum {
59cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        is_pointer          = false,
60a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        has_trivial_ctor    =
61a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
62a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        has_trivial_dtor    =
63a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
64a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        has_trivial_copy    =
65a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
66a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        has_trivial_move    =
67a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            traits<T>::has_trivial_move && traits<U>::has_trivial_move
68cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    };
69cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project};
70cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
719a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
729a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    template<> struct trait_trivial_ctor< T >   { enum { value = true }; };
739a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown
749a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
759a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    template<> struct trait_trivial_dtor< T >   { enum { value = true }; };
769a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown
779a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
789a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    template<> struct trait_trivial_copy< T >   { enum { value = true }; };
799a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown
809a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
81a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian    template<> struct trait_trivial_move< T >   { enum { value = true }; };
82a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
839a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_BASIC_TYPES_TRAITS( T ) \
849a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
859a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
869a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    ANDROID_TRIVIAL_COPY_TRAIT( T ) \
879a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    ANDROID_TRIVIAL_MOVE_TRAIT( T )
889a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown
89cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
90cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
91cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
92cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * basic types traits
93cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
94a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
95a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( void )
96a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( bool )
97a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( char )
98a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned char )
99a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( short )
100a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned short )
101a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( int )
102a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned int )
103a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( long )
104a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned long )
105a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( long long )
106a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned long long )
107a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( float )
108a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( double )
109cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
110cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
111cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
112a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
113cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
114cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * compare and order types
115cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
116cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
117cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
118cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
119cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return (lhs < rhs) ? 1 : 0;
120cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
121cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
122cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
123cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint compare_type(const TYPE& lhs, const TYPE& rhs) {
124cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
125cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
126cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
127cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
128a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian * create, destroy, copy and move types...
129cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
130a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
131cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
132cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid construct_type(TYPE* p, size_t n) {
133cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (!traits<TYPE>::has_trivial_ctor) {
134cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        while (n--) {
135cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            new(p++) TYPE;
136cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
137cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
138cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
139cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
140cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
141cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid destroy_type(TYPE* p, size_t n) {
142cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (!traits<TYPE>::has_trivial_dtor) {
143cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        while (n--) {
144cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            p->~TYPE();
145cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            p++;
146cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
147cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
148cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
149cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
150cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
151cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid copy_type(TYPE* d, const TYPE* s, size_t n) {
152cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (!traits<TYPE>::has_trivial_copy) {
153cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        while (n--) {
154cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            new(d) TYPE(*s);
155cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            d++, s++;
156cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
157cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    } else {
158cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        memcpy(d,s,n*sizeof(TYPE));
159cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
160cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
161cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
162cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
163cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid splat_type(TYPE* where, const TYPE* what, size_t n) {
164cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (!traits<TYPE>::has_trivial_copy) {
165cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        while (n--) {
166cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            new(where) TYPE(*what);
167cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            where++;
168cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
169cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    } else {
170a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        while (n--) {
171a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            *where++ = *what;
172cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
173cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
174cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
175cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
176cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
177cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
178a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
179a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            || traits<TYPE>::has_trivial_move)
180a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian    {
181a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        memmove(d,s,n*sizeof(TYPE));
182a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian    } else {
183cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        d += n;
184cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        s += n;
185cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        while (n--) {
186cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            --d, --s;
187cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            if (!traits<TYPE>::has_trivial_copy) {
188cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                new(d) TYPE(*s);
189cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            } else {
190a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian                *d = *s;
191cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            }
192cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            if (!traits<TYPE>::has_trivial_dtor) {
193cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                s->~TYPE();
194cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            }
195cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
196cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
197cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
198cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
199cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
200cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
201a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
202a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            || traits<TYPE>::has_trivial_move)
203a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian    {
204a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        memmove(d,s,n*sizeof(TYPE));
205a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian    } else {
206cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        while (n--) {
207cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            if (!traits<TYPE>::has_trivial_copy) {
208cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                new(d) TYPE(*s);
209cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            } else {
210a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian                *d = *s;
211cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            }
212cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            if (!traits<TYPE>::has_trivial_dtor) {
213cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project                s->~TYPE();
214cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            }
215cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            d++, s++;
216cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
217cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
218cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
219a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
220cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
221cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
222cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
223cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * a key/value pair
224cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
225cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
226cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename KEY, typename VALUE>
227cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct key_value_pair_t {
228e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    typedef KEY key_t;
229e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    typedef VALUE value_t;
230e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
231cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    KEY     key;
232cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    VALUE   value;
233cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    key_value_pair_t() { }
234cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
235cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
236cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    key_value_pair_t(const KEY& k) : key(k) { }
237cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    inline bool operator < (const key_value_pair_t& o) const {
238cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        return strictly_order_type(key, o.key);
239cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
240e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    inline const KEY& getKey() const {
241e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        return key;
242e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    }
243e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    inline const VALUE& getValue() const {
244e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        return value;
245e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    }
246cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project};
247cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
248cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename K, typename V>
249cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct trait_trivial_ctor< key_value_pair_t<K, V> >
250cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
251cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename K, typename V>
252cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct trait_trivial_dtor< key_value_pair_t<K, V> >
253cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
254cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename K, typename V>
255cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct trait_trivial_copy< key_value_pair_t<K, V> >
256cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
257cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename K, typename V>
258a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopianstruct trait_trivial_move< key_value_pair_t<K, V> >
259a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
260cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
261cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
262cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
263e735f23018b398f45bd052b63616d7a45e29515bJeff Brown/*
264e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * Hash codes.
265e735f23018b398f45bd052b63616d7a45e29515bJeff Brown */
266e735f23018b398f45bd052b63616d7a45e29515bJeff Browntypedef uint32_t hash_t;
267e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
268e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <typename TKey>
269e735f23018b398f45bd052b63616d7a45e29515bJeff Brownhash_t hash_type(const TKey& key);
270e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
271e735f23018b398f45bd052b63616d7a45e29515bJeff Brown/* Built-in hash code specializations.
272e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * Assumes pointers are 32bit. */
273e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#define ANDROID_INT32_HASH(T) \
274e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
275e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#define ANDROID_INT64_HASH(T) \
276e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        template <> inline hash_t hash_type(const T& value) { \
277e735f23018b398f45bd052b63616d7a45e29515bJeff Brown                return hash_t((value >> 32) ^ value); }
278e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#define ANDROID_REINTERPRET_HASH(T, R) \
279e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        template <> inline hash_t hash_type(const T& value) { \
280e735f23018b398f45bd052b63616d7a45e29515bJeff Brown                return hash_type(*reinterpret_cast<const R*>(&value)); }
281e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
282e735f23018b398f45bd052b63616d7a45e29515bJeff BrownANDROID_INT32_HASH(bool)
283142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(int8_t)
284142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(uint8_t)
285142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(int16_t)
286142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(uint16_t)
287142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(int32_t)
288142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(uint32_t)
289142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT64_HASH(int64_t)
290142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT64_HASH(uint64_t)
291e735f23018b398f45bd052b63616d7a45e29515bJeff BrownANDROID_REINTERPRET_HASH(float, uint32_t)
292e735f23018b398f45bd052b63616d7a45e29515bJeff BrownANDROID_REINTERPRET_HASH(double, uint64_t)
293e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
294b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levientemplate <typename T> inline hash_t hash_type(T* const & value) {
295e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    return hash_type(uintptr_t(value));
296e735f23018b398f45bd052b63616d7a45e29515bJeff Brown}
297e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
298cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android
299cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
300cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
301cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
302cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif // ANDROID_TYPE_HELPERS_H
303