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