/* * Copyright (C) 2005 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_TYPE_HELPERS_H #define ANDROID_TYPE_HELPERS_H #include #include #include #include // --------------------------------------------------------------------------- namespace android { /* * Types traits */ template struct trait_trivial_ctor { enum { value = false }; }; template struct trait_trivial_dtor { enum { value = false }; }; template struct trait_trivial_copy { enum { value = false }; }; template struct trait_trivial_assign{ enum { value = false }; }; template struct trait_pointer { enum { value = false }; }; template struct trait_pointer { enum { value = true }; }; #define ANDROID_BASIC_TYPES_TRAITS( T ) \ template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \ template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \ template<> struct trait_trivial_copy< T > { enum { value = true }; }; \ template<> struct trait_trivial_assign< T >{ enum { value = true }; }; #define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign ) \ template<> struct trait_trivial_ctor< T > { enum { value = ctor }; }; \ template<> struct trait_trivial_dtor< T > { enum { value = dtor }; }; \ template<> struct trait_trivial_copy< T > { enum { value = copy }; }; \ template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; template struct traits { enum { is_pointer = trait_pointer::value, has_trivial_ctor = is_pointer || trait_trivial_ctor::value, has_trivial_dtor = is_pointer || trait_trivial_dtor::value, has_trivial_copy = is_pointer || trait_trivial_copy::value, has_trivial_assign = is_pointer || trait_trivial_assign::value }; }; template struct aggregate_traits { enum { is_pointer = false, has_trivial_ctor = traits::has_trivial_ctor && traits::has_trivial_ctor, has_trivial_dtor = traits::has_trivial_dtor && traits::has_trivial_dtor, has_trivial_copy = traits::has_trivial_copy && traits::has_trivial_copy, has_trivial_assign = traits::has_trivial_assign && traits::has_trivial_assign }; }; // --------------------------------------------------------------------------- /* * basic types traits */ ANDROID_BASIC_TYPES_TRAITS( void ); ANDROID_BASIC_TYPES_TRAITS( bool ); ANDROID_BASIC_TYPES_TRAITS( char ); ANDROID_BASIC_TYPES_TRAITS( unsigned char ); ANDROID_BASIC_TYPES_TRAITS( short ); ANDROID_BASIC_TYPES_TRAITS( unsigned short ); ANDROID_BASIC_TYPES_TRAITS( int ); ANDROID_BASIC_TYPES_TRAITS( unsigned int ); ANDROID_BASIC_TYPES_TRAITS( long ); ANDROID_BASIC_TYPES_TRAITS( unsigned long ); ANDROID_BASIC_TYPES_TRAITS( long long ); ANDROID_BASIC_TYPES_TRAITS( unsigned long long ); ANDROID_BASIC_TYPES_TRAITS( float ); ANDROID_BASIC_TYPES_TRAITS( double ); // --------------------------------------------------------------------------- /* * compare and order types */ template inline int strictly_order_type(const TYPE& lhs, const TYPE& rhs) { return (lhs < rhs) ? 1 : 0; } template inline int compare_type(const TYPE& lhs, const TYPE& rhs) { return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs); } /* * create, destroy, copy and assign types... */ template inline void construct_type(TYPE* p, size_t n) { if (!traits::has_trivial_ctor) { while (n--) { new(p++) TYPE; } } } template inline void destroy_type(TYPE* p, size_t n) { if (!traits::has_trivial_dtor) { while (n--) { p->~TYPE(); p++; } } } template inline void copy_type(TYPE* d, const TYPE* s, size_t n) { if (!traits::has_trivial_copy) { while (n--) { new(d) TYPE(*s); d++, s++; } } else { memcpy(d,s,n*sizeof(TYPE)); } } template inline void assign_type(TYPE* d, const TYPE* s, size_t n) { if (!traits::has_trivial_assign) { while (n--) { *d++ = *s++; } } else { memcpy(d,s,n*sizeof(TYPE)); } } template inline void splat_type(TYPE* where, const TYPE* what, size_t n) { if (!traits::has_trivial_copy) { while (n--) { new(where) TYPE(*what); where++; } } else { while (n--) { *where++ = *what; } } } template inline void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { if (!traits::has_trivial_copy || !traits::has_trivial_dtor) { d += n; s += n; while (n--) { --d, --s; if (!traits::has_trivial_copy) { new(d) TYPE(*s); } else { *d = *s; } if (!traits::has_trivial_dtor) { s->~TYPE(); } } } else { memmove(d,s,n*sizeof(TYPE)); } } template inline void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { if (!traits::has_trivial_copy || !traits::has_trivial_dtor) { while (n--) { if (!traits::has_trivial_copy) { new(d) TYPE(*s); } else { *d = *s; } if (!traits::has_trivial_dtor) { s->~TYPE(); } d++, s++; } } else { memmove(d,s,n*sizeof(TYPE)); } } // --------------------------------------------------------------------------- /* * a key/value pair */ template struct key_value_pair_t { KEY key; VALUE value; key_value_pair_t() { } key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { } key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { } key_value_pair_t(const KEY& k) : key(k) { } inline bool operator < (const key_value_pair_t& o) const { return strictly_order_type(key, o.key); } }; template<> template struct trait_trivial_ctor< key_value_pair_t > { enum { value = aggregate_traits::has_trivial_ctor }; }; template<> template struct trait_trivial_dtor< key_value_pair_t > { enum { value = aggregate_traits::has_trivial_dtor }; }; template<> template struct trait_trivial_copy< key_value_pair_t > { enum { value = aggregate_traits::has_trivial_copy }; }; template<> template struct trait_trivial_assign< key_value_pair_t > { enum { value = aggregate_traits::has_trivial_assign};}; // --------------------------------------------------------------------------- }; // namespace android // --------------------------------------------------------------------------- #endif // ANDROID_TYPE_HELPERS_H