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>
2117b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross#include <type_traits>
2217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross
23cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <stdint.h>
24cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <string.h>
25cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <sys/types.h>
26cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
27cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
28cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
29cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectnamespace android {
30cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
31cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
32cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Types traits
33cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
34a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
35a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_trivial_ctor { enum { value = false }; };
36a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_trivial_dtor { enum { value = false }; };
37a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_trivial_copy { enum { value = false }; };
38a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_trivial_move { enum { value = false }; };
39fc3f57acbb11455bc917f9e622c526c01c3843ffVishwath Mohantemplate <typename T> struct trait_pointer      { enum { value = false }; };
40a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopiantemplate <typename T> struct trait_pointer<T*>  { enum { value = true }; };
41a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
42cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename TYPE>
43cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct traits {
44cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    enum {
45a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type is a pointer
46cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        is_pointer          = trait_pointer<TYPE>::value,
47a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type's constructor is a no-op
48cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
49a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type's destructor is a no-op
50cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
51a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type type can be copy-constructed with memcpy
52cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
53a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        // whether this type can be moved with memmove
54a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian        has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    };
56cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project};
57cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
58cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename T, typename U>
59cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct aggregate_traits {
60cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    enum {
61cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        is_pointer          = false,
62fc3f57acbb11455bc917f9e622c526c01c3843ffVishwath Mohan        has_trivial_ctor    =
63a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
64fc3f57acbb11455bc917f9e622c526c01c3843ffVishwath Mohan        has_trivial_dtor    =
65a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
66fc3f57acbb11455bc917f9e622c526c01c3843ffVishwath Mohan        has_trivial_copy    =
67a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
68fc3f57acbb11455bc917f9e622c526c01c3843ffVishwath Mohan        has_trivial_move    =
69a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            traits<T>::has_trivial_move && traits<U>::has_trivial_move
70cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    };
71cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project};
72cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
739a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
749a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    template<> struct trait_trivial_ctor< T >   { enum { value = true }; };
759a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown
769a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
779a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    template<> struct trait_trivial_dtor< T >   { enum { value = true }; };
789a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown
799a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
809a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    template<> struct trait_trivial_copy< T >   { enum { value = true }; };
819a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown
829a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
83a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian    template<> struct trait_trivial_move< T >   { enum { value = true }; };
84a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
859a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown#define ANDROID_BASIC_TYPES_TRAITS( T ) \
869a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
879a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
889a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    ANDROID_TRIVIAL_COPY_TRAIT( T ) \
899a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown    ANDROID_TRIVIAL_MOVE_TRAIT( T )
909a0a76df1e961ef4621e81814d8bf891a09bef66Jeff Brown
91cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
92cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
93cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
94cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * basic types traits
95cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
96a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
97a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( void )
98a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( bool )
99a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( char )
100a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned char )
101a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( short )
102a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned short )
103a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( int )
104a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned int )
105a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( long )
106a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned long )
107a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( long long )
108a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( unsigned long long )
109a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( float )
110a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias AgopianANDROID_BASIC_TYPES_TRAITS( double )
111cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
112cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
113cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
114a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
115cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
116cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * compare and order types
117cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
118cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
119cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
120cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
121cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return (lhs < rhs) ? 1 : 0;
122cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
123cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
124cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
125cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint compare_type(const TYPE& lhs, const TYPE& rhs) {
126cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
127cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
128cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
129cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
130a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian * create, destroy, copy and move types...
131cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
132a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
133cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
134cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid construct_type(TYPE* p, size_t n) {
135cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (!traits<TYPE>::has_trivial_ctor) {
13658bf572aa2060ad30a8e46dd0b4a5cf9bb748f85Nick Kralevich        while (n > 0) {
13758bf572aa2060ad30a8e46dd0b4a5cf9bb748f85Nick Kralevich            n--;
138cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            new(p++) TYPE;
139cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
140cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
141cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
142cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
143cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
144cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid destroy_type(TYPE* p, size_t n) {
145cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (!traits<TYPE>::has_trivial_dtor) {
14658bf572aa2060ad30a8e46dd0b4a5cf9bb748f85Nick Kralevich        while (n > 0) {
14758bf572aa2060ad30a8e46dd0b4a5cf9bb748f85Nick Kralevich            n--;
148cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            p->~TYPE();
149cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            p++;
150cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
151cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
152cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
153cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
1541811d156e9c6b5486d25090ec3e911632dc6edffColin Crosstemplate<typename TYPE>
1551811d156e9c6b5486d25090ec3e911632dc6edffColin Crosstypename std::enable_if<traits<TYPE>::has_trivial_copy>::type
1561811d156e9c6b5486d25090ec3e911632dc6edffColin Crossinline
1571811d156e9c6b5486d25090ec3e911632dc6edffColin Crosscopy_type(TYPE* d, const TYPE* s, size_t n) {
1581811d156e9c6b5486d25090ec3e911632dc6edffColin Cross    memcpy(d,s,n*sizeof(TYPE));
1591811d156e9c6b5486d25090ec3e911632dc6edffColin Cross}
1601811d156e9c6b5486d25090ec3e911632dc6edffColin Cross
1611811d156e9c6b5486d25090ec3e911632dc6edffColin Crosstemplate<typename TYPE>
1621811d156e9c6b5486d25090ec3e911632dc6edffColin Crosstypename std::enable_if<!traits<TYPE>::has_trivial_copy>::type
1631811d156e9c6b5486d25090ec3e911632dc6edffColin Crossinline
1641811d156e9c6b5486d25090ec3e911632dc6edffColin Crosscopy_type(TYPE* d, const TYPE* s, size_t n) {
1651811d156e9c6b5486d25090ec3e911632dc6edffColin Cross    while (n > 0) {
1661811d156e9c6b5486d25090ec3e911632dc6edffColin Cross        n--;
1671811d156e9c6b5486d25090ec3e911632dc6edffColin Cross        new(d) TYPE(*s);
1681811d156e9c6b5486d25090ec3e911632dc6edffColin Cross        d++, s++;
169cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
170cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
171cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
172cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate<typename TYPE> inline
173cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid splat_type(TYPE* where, const TYPE* what, size_t n) {
174cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    if (!traits<TYPE>::has_trivial_copy) {
17558bf572aa2060ad30a8e46dd0b4a5cf9bb748f85Nick Kralevich        while (n > 0) {
17658bf572aa2060ad30a8e46dd0b4a5cf9bb748f85Nick Kralevich            n--;
177cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            new(where) TYPE(*what);
178cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project            where++;
179cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
180cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    } else {
18158bf572aa2060ad30a8e46dd0b4a5cf9bb748f85Nick Kralevich        while (n > 0) {
18258bf572aa2060ad30a8e46dd0b4a5cf9bb748f85Nick Kralevich            n--;
183a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian            *where++ = *what;
184cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
185cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
186cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
187cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
18817b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstemplate<typename TYPE>
18917b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossstruct use_trivial_move : public std::integral_constant<bool,
19017b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    (traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
19117b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    || traits<TYPE>::has_trivial_move
19217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross> {};
19317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross
19417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstemplate<typename TYPE>
19517b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstypename std::enable_if<use_trivial_move<TYPE>::value>::type
19617b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossinline
19717b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossmove_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
19817b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    memmove(d, s, n*sizeof(TYPE));
19917b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross}
20017b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross
20117b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstemplate<typename TYPE>
20217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstypename std::enable_if<!use_trivial_move<TYPE>::value>::type
20317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossinline
20417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossmove_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
20517b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    d += n;
20617b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    s += n;
20717b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    while (n > 0) {
20817b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        n--;
20917b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        --d, --s;
21017b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        if (!traits<TYPE>::has_trivial_copy) {
21117b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            new(d) TYPE(*s);
21217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        } else {
21317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            *d = *s;
21417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        }
21517b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        if (!traits<TYPE>::has_trivial_dtor) {
21617b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            s->~TYPE();
217cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
218cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
219cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
220cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
22117b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstemplate<typename TYPE>
22217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstypename std::enable_if<use_trivial_move<TYPE>::value>::type
22317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossinline
22417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossmove_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
22517b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    memmove(d, s, n*sizeof(TYPE));
22617b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross}
22717b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross
22817b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstemplate<typename TYPE>
22917b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crosstypename std::enable_if<!use_trivial_move<TYPE>::value>::type
23017b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossinline
23117b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Crossmove_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
23217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    while (n > 0) {
23317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        n--;
23417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        if (!traits<TYPE>::has_trivial_copy) {
23517b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            new(d) TYPE(*s);
23617b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        } else {
23717b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            *d = *s;
23817b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        }
23917b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        if (!traits<TYPE>::has_trivial_dtor) {
24017b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            s->~TYPE();
241cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        }
24217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        d++, s++;
243cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
244cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}
245a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian
246cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
247cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
248cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/*
249cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * a key/value pair
250cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */
251cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
252cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename KEY, typename VALUE>
253cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct key_value_pair_t {
254e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    typedef KEY key_t;
255e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    typedef VALUE value_t;
256e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
257cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    KEY     key;
258cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    VALUE   value;
259cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    key_value_pair_t() { }
260cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
26117b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    key_value_pair_t& operator=(const key_value_pair_t& o) {
26217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        key = o.key;
26317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        value = o.value;
26417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        return *this;
26517b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross    }
266cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
2672a929968e1038d1940bab08a678263db3c2655eaChih-Hung Hsieh    explicit key_value_pair_t(const KEY& k) : key(k) { }
268cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    inline bool operator < (const key_value_pair_t& o) const {
269cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project        return strictly_order_type(key, o.key);
270cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project    }
271e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    inline const KEY& getKey() const {
272e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        return key;
273e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    }
274e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    inline const VALUE& getValue() const {
275e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        return value;
276e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    }
277cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project};
278cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
279cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename K, typename V>
280cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct trait_trivial_ctor< key_value_pair_t<K, V> >
281cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
282cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename K, typename V>
283cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct trait_trivial_dtor< key_value_pair_t<K, V> >
284cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
285cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename K, typename V>
286cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstruct trait_trivial_copy< key_value_pair_t<K, V> >
287cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
288cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projecttemplate <typename K, typename V>
289a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopianstruct trait_trivial_move< key_value_pair_t<K, V> >
290a33bd1672fab3ac2ca72f2921716bf860d500aa3Mathias Agopian{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
291cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
292cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
293cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
294e735f23018b398f45bd052b63616d7a45e29515bJeff Brown/*
295e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * Hash codes.
296e735f23018b398f45bd052b63616d7a45e29515bJeff Brown */
297e735f23018b398f45bd052b63616d7a45e29515bJeff Browntypedef uint32_t hash_t;
298e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
299e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <typename TKey>
300e735f23018b398f45bd052b63616d7a45e29515bJeff Brownhash_t hash_type(const TKey& key);
301e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
30217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross/* Built-in hash code specializations */
303e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#define ANDROID_INT32_HASH(T) \
304e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
305e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#define ANDROID_INT64_HASH(T) \
306e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        template <> inline hash_t hash_type(const T& value) { \
307e735f23018b398f45bd052b63616d7a45e29515bJeff Brown                return hash_t((value >> 32) ^ value); }
308e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#define ANDROID_REINTERPRET_HASH(T, R) \
309e735f23018b398f45bd052b63616d7a45e29515bJeff Brown        template <> inline hash_t hash_type(const T& value) { \
31017b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            R newValue; \
31117b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            static_assert(sizeof(newValue) == sizeof(value), "size mismatch"); \
31217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            memcpy(&newValue, &value, sizeof(newValue)); \
31317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross            return hash_type(newValue); \
31417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross        }
315e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
316e735f23018b398f45bd052b63616d7a45e29515bJeff BrownANDROID_INT32_HASH(bool)
317142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(int8_t)
318142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(uint8_t)
319142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(int16_t)
320142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(uint16_t)
321142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(int32_t)
322142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT32_HASH(uint32_t)
323142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT64_HASH(int64_t)
324142dbcd817ac7960061735e5e7ea174e0938fb09Jeff BrownANDROID_INT64_HASH(uint64_t)
325e735f23018b398f45bd052b63616d7a45e29515bJeff BrownANDROID_REINTERPRET_HASH(float, uint32_t)
326e735f23018b398f45bd052b63616d7a45e29515bJeff BrownANDROID_REINTERPRET_HASH(double, uint64_t)
327e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
328b6ea175b6b4d0aaac85ed6cd8ccac01ab896486bRaph Levientemplate <typename T> inline hash_t hash_type(T* const & value) {
329e735f23018b398f45bd052b63616d7a45e29515bJeff Brown    return hash_type(uintptr_t(value));
330e735f23018b398f45bd052b63616d7a45e29515bJeff Brown}
331e735f23018b398f45bd052b63616d7a45e29515bJeff Brown
332cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android
333cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
334cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// ---------------------------------------------------------------------------
335cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project
336cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif // ANDROID_TYPE_HELPERS_H
337