Home | History | Annotate | Download | only in tinyutils
      1 /*
      2  *  TypeHelpers.h
      3  *
      4  *  Copyright 2005 The Android Open Source Project
      5  *
      6  */
      7 
      8 #ifndef ANDROID_TYPE_HELPERS_H
      9 #define ANDROID_TYPE_HELPERS_H
     10 
     11 #include <new>
     12 #include <stdint.h>
     13 #include <string.h>
     14 #include <sys/types.h>
     15 
     16 // ---------------------------------------------------------------------------
     17 
     18 namespace android {
     19 
     20 /*
     21  * Types traits
     22  */
     23 
     24 template <typename T> struct trait_trivial_ctor  { enum { value = false }; };
     25 template <typename T> struct trait_trivial_dtor  { enum { value = false }; };
     26 template <typename T> struct trait_trivial_copy  { enum { value = false }; };
     27 template <typename T> struct trait_trivial_assign{ enum { value = false }; };
     28 
     29 template <typename T> struct trait_pointer     { enum { value = false }; };
     30 template <typename T> struct trait_pointer<T*> { enum { value = true }; };
     31 
     32 #define ANDROID_BASIC_TYPES_TRAITS( T )                                       \
     33     template<> struct trait_trivial_ctor< T >  { enum { value = true }; };    \
     34     template<> struct trait_trivial_dtor< T >  { enum { value = true }; };    \
     35     template<> struct trait_trivial_copy< T >  { enum { value = true }; };    \
     36     template<> struct trait_trivial_assign< T >{ enum { value = true }; };
     37 
     38 #define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign )                    \
     39     template<> struct trait_trivial_ctor< T >  { enum { value = ctor }; };    \
     40     template<> struct trait_trivial_dtor< T >  { enum { value = dtor }; };    \
     41     template<> struct trait_trivial_copy< T >  { enum { value = copy }; };    \
     42     template<> struct trait_trivial_assign< T >{ enum { value = assign }; };
     43 
     44 template <typename TYPE>
     45 struct traits {
     46     enum {
     47         is_pointer          = trait_pointer<TYPE>::value,
     48         has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
     49         has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
     50         has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
     51         has_trivial_assign  = is_pointer || trait_trivial_assign<TYPE>::value
     52     };
     53 };
     54 
     55 template <typename T, typename U>
     56 struct aggregate_traits {
     57     enum {
     58         is_pointer          = false,
     59         has_trivial_ctor    = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
     60         has_trivial_dtor    = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
     61         has_trivial_copy    = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
     62         has_trivial_assign  = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign
     63     };
     64 };
     65 
     66 // ---------------------------------------------------------------------------
     67 
     68 /*
     69  * basic types traits
     70  */
     71 
     72 ANDROID_BASIC_TYPES_TRAITS( void );
     73 ANDROID_BASIC_TYPES_TRAITS( bool );
     74 ANDROID_BASIC_TYPES_TRAITS( char );
     75 ANDROID_BASIC_TYPES_TRAITS( unsigned char );
     76 ANDROID_BASIC_TYPES_TRAITS( short );
     77 ANDROID_BASIC_TYPES_TRAITS( unsigned short );
     78 ANDROID_BASIC_TYPES_TRAITS( int );
     79 ANDROID_BASIC_TYPES_TRAITS( unsigned int );
     80 ANDROID_BASIC_TYPES_TRAITS( long );
     81 ANDROID_BASIC_TYPES_TRAITS( unsigned long );
     82 ANDROID_BASIC_TYPES_TRAITS( long long );
     83 ANDROID_BASIC_TYPES_TRAITS( unsigned long long );
     84 ANDROID_BASIC_TYPES_TRAITS( float );
     85 ANDROID_BASIC_TYPES_TRAITS( double );
     86 
     87 // ---------------------------------------------------------------------------
     88 
     89 
     90 /*
     91  * compare and order types
     92  */
     93 
     94 template<typename TYPE> inline
     95 int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
     96     return (lhs < rhs) ? 1 : 0;
     97 }
     98 
     99 template<typename TYPE> inline
    100 int compare_type(const TYPE& lhs, const TYPE& rhs) {
    101     return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
    102 }
    103 
    104 /*
    105  * create, destroy, copy and assign types...
    106  */
    107 
    108 template<typename TYPE> inline
    109 void construct_type(TYPE* p, size_t n) {
    110     if (!traits<TYPE>::has_trivial_ctor) {
    111         while (n--) {
    112             new(p++) TYPE;
    113         }
    114     }
    115 }
    116 
    117 template<typename TYPE> inline
    118 void destroy_type(TYPE* p, size_t n) {
    119     if (!traits<TYPE>::has_trivial_dtor) {
    120         while (n--) {
    121             p->~TYPE();
    122             p++;
    123         }
    124     }
    125 }
    126 
    127 template<typename TYPE> inline
    128 void copy_type(TYPE* d, const TYPE* s, size_t n) {
    129     if (!traits<TYPE>::has_trivial_copy) {
    130         while (n--) {
    131             new(d) TYPE(*s);
    132             d++, s++;
    133         }
    134     } else {
    135         memcpy(d,s,n*sizeof(TYPE));
    136     }
    137 }
    138 
    139 template<typename TYPE> inline
    140 void assign_type(TYPE* d, const TYPE* s, size_t n) {
    141     if (!traits<TYPE>::has_trivial_assign) {
    142         while (n--) {
    143             *d++ = *s++;
    144         }
    145     } else {
    146         memcpy(d,s,n*sizeof(TYPE));
    147     }
    148 }
    149 
    150 template<typename TYPE> inline
    151 void splat_type(TYPE* where, const TYPE* what, size_t n) {
    152     if (!traits<TYPE>::has_trivial_copy) {
    153         while (n--) {
    154             new(where) TYPE(*what);
    155             where++;
    156         }
    157     } else {
    158          while (n--) {
    159              *where++ = *what;
    160         }
    161     }
    162 }
    163 
    164 template<typename TYPE> inline
    165 void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    166     if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
    167         d += n;
    168         s += n;
    169         while (n--) {
    170             --d, --s;
    171             if (!traits<TYPE>::has_trivial_copy) {
    172                 new(d) TYPE(*s);
    173             } else {
    174                 *d = *s;
    175             }
    176             if (!traits<TYPE>::has_trivial_dtor) {
    177                 s->~TYPE();
    178             }
    179         }
    180     } else {
    181         memmove(d,s,n*sizeof(TYPE));
    182     }
    183 }
    184 
    185 template<typename TYPE> inline
    186 void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    187     if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
    188         while (n--) {
    189             if (!traits<TYPE>::has_trivial_copy) {
    190                 new(d) TYPE(*s);
    191             } else {
    192                 *d = *s;
    193             }
    194             if (!traits<TYPE>::has_trivial_dtor) {
    195                 s->~TYPE();
    196             }
    197             d++, s++;
    198         }
    199     } else {
    200         memmove(d,s,n*sizeof(TYPE));
    201     }
    202 }
    203 // ---------------------------------------------------------------------------
    204 
    205 /*
    206  * a key/value pair
    207  */
    208 
    209 template <typename KEY, typename VALUE>
    210 struct key_value_pair_t {
    211     KEY     key;
    212     VALUE   value;
    213     key_value_pair_t() { }
    214     key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
    215     key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
    216     key_value_pair_t(const KEY& k) : key(k) { }
    217     inline bool operator < (const key_value_pair_t& o) const {
    218         return strictly_order_type(key, o.key);
    219     }
    220 };
    221 
    222 template<>
    223 template <typename K, typename V>
    224 struct trait_trivial_ctor< key_value_pair_t<K, V> >
    225 { enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
    226 template<>
    227 template <typename K, typename V>
    228 struct trait_trivial_dtor< key_value_pair_t<K, V> >
    229 { enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
    230 template<>
    231 template <typename K, typename V>
    232 struct trait_trivial_copy< key_value_pair_t<K, V> >
    233 { enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
    234 template<>
    235 template <typename K, typename V>
    236 struct trait_trivial_assign< key_value_pair_t<K, V> >
    237 { enum { value = aggregate_traits<K,V>::has_trivial_assign};};
    238 
    239 // ---------------------------------------------------------------------------
    240 
    241 }; // namespace android
    242 
    243 // ---------------------------------------------------------------------------
    244 
    245 #endif // ANDROID_TYPE_HELPERS_H
    246