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