LCOV - code coverage report
Current view: top level - media/libstagefright/system/core/include/utils - TypeHelpers.h (source / functions) Hit Total Coverage
Test: output.info Lines: 15 49 30.6 %
Date: 2017-07-14 16:53:18 Functions: 3 27 11.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 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_TYPE_HELPERS_H
      18             : #define ANDROID_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 stagefright {
      28             : 
      29             : /*
      30             :  * Types traits
      31             :  */
      32             : 
      33             : template <typename T> struct trait_trivial_ctor { enum { value = false }; };
      34             : template <typename T> struct trait_trivial_dtor { enum { value = false }; };
      35             : template <typename T> struct trait_trivial_copy { enum { value = false }; };
      36             : template <typename T> struct trait_trivial_move { enum { value = false }; };
      37             : template <typename T> struct trait_pointer      { enum { value = false }; };    
      38             : template <typename T> struct trait_pointer<T*>  { enum { value = true }; };
      39             : 
      40             : template <typename TYPE>
      41             : struct traits {
      42             :     enum {
      43             :         // whether this type is a pointer
      44             :         is_pointer          = trait_pointer<TYPE>::value,
      45             :         // whether this type's constructor is a no-op
      46             :         has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
      47             :         // whether this type's destructor is a no-op
      48             :         has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
      49             :         // whether this type type can be copy-constructed with memcpy
      50             :         has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
      51             :         // whether this type can be moved with memmove
      52             :         has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
      53             :     };
      54             : };
      55             : 
      56             : template <typename T, typename U>
      57             : struct aggregate_traits {
      58             :     enum {
      59             :         is_pointer          = false,
      60             :         has_trivial_ctor    = 
      61             :             traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
      62             :         has_trivial_dtor    = 
      63             :             traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
      64             :         has_trivial_copy    = 
      65             :             traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
      66             :         has_trivial_move    = 
      67             :             traits<T>::has_trivial_move && traits<U>::has_trivial_move
      68             :     };
      69             : };
      70             : 
      71             : #define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
      72             :     template<> struct trait_trivial_ctor< T >   { enum { value = true }; };
      73             : 
      74             : #define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
      75             :     template<> struct trait_trivial_dtor< T >   { enum { value = true }; };
      76             : 
      77             : #define ANDROID_TRIVIAL_COPY_TRAIT( T ) \
      78             :     template<> struct trait_trivial_copy< T >   { enum { value = true }; };
      79             : 
      80             : #define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \
      81             :     template<> struct trait_trivial_move< T >   { enum { value = true }; };
      82             : 
      83             : #define ANDROID_BASIC_TYPES_TRAITS( T ) \
      84             :     ANDROID_TRIVIAL_CTOR_TRAIT( T ) \
      85             :     ANDROID_TRIVIAL_DTOR_TRAIT( T ) \
      86             :     ANDROID_TRIVIAL_COPY_TRAIT( T ) \
      87             :     ANDROID_TRIVIAL_MOVE_TRAIT( T )
      88             : 
      89             : // ---------------------------------------------------------------------------
      90             : 
      91             : /*
      92             :  * basic types traits
      93             :  */
      94             : 
      95             : ANDROID_BASIC_TYPES_TRAITS( void )
      96             : ANDROID_BASIC_TYPES_TRAITS( bool )
      97             : ANDROID_BASIC_TYPES_TRAITS( char )
      98             : ANDROID_BASIC_TYPES_TRAITS( unsigned char )
      99             : ANDROID_BASIC_TYPES_TRAITS( short )
     100             : ANDROID_BASIC_TYPES_TRAITS( unsigned short )
     101             : ANDROID_BASIC_TYPES_TRAITS( int )
     102             : ANDROID_BASIC_TYPES_TRAITS( unsigned int )
     103             : ANDROID_BASIC_TYPES_TRAITS( long )
     104             : ANDROID_BASIC_TYPES_TRAITS( unsigned long )
     105             : ANDROID_BASIC_TYPES_TRAITS( long long )
     106             : ANDROID_BASIC_TYPES_TRAITS( unsigned long long )
     107             : ANDROID_BASIC_TYPES_TRAITS( float )
     108             : ANDROID_BASIC_TYPES_TRAITS( double )
     109             : 
     110             : // ---------------------------------------------------------------------------
     111             : 
     112             : 
     113             : /*
     114             :  * compare and order types
     115             :  */
     116             : 
     117             : template<typename TYPE> inline
     118           0 : int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
     119           0 :     return (lhs < rhs) ? 1 : 0;
     120             : }
     121             : 
     122             : template<typename TYPE> inline
     123           0 : int compare_type(const TYPE& lhs, const TYPE& rhs) {
     124           0 :     return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
     125             : }
     126             : 
     127             : /*
     128             :  * create, destroy, copy and move types...
     129             :  */
     130             : 
     131             : template<typename TYPE> inline
     132           0 : void construct_type(TYPE* p, size_t n) {
     133             :     if (!traits<TYPE>::has_trivial_ctor) {
     134           0 :         while (n--) {
     135           0 :             new(p++) TYPE;
     136             :         }
     137             :     }
     138           0 : }
     139             : 
     140             : template<typename TYPE> inline
     141         702 : void destroy_type(TYPE* p, size_t n) {
     142             :     if (!traits<TYPE>::has_trivial_dtor) {
     143        1383 :         while (n--) {
     144         681 :             p->~TYPE();
     145         681 :             p++;
     146             :         }
     147             :     }
     148          21 : }
     149             : 
     150             : template<typename TYPE> inline
     151          21 : void copy_type(TYPE* d, const TYPE* s, size_t n) {
     152             :     if (!traits<TYPE>::has_trivial_copy) {
     153        1383 :         while (n--) {
     154         681 :             new(d) TYPE(*s);
     155         681 :             d++, s++;
     156             :         }
     157             :     } else {
     158           0 :         memcpy(d,s,n*sizeof(TYPE));
     159             :     }
     160          21 : }
     161             : 
     162             : template<typename TYPE> inline
     163         384 : void splat_type(TYPE* where, const TYPE* what, size_t n) {
     164             :     if (!traits<TYPE>::has_trivial_copy) {
     165        1152 :         while (n--) {
     166         384 :             new(where) TYPE(*what);
     167         384 :             where++;
     168             :         }
     169             :     } else {
     170           0 :         while (n--) {
     171           0 :             *where++ = *what;
     172             :         }
     173             :     }
     174         384 : }
     175             : 
     176             : template<typename TYPE> inline
     177           0 : void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
     178             :     if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) 
     179             :             || traits<TYPE>::has_trivial_move) 
     180             :     {
     181           0 :         memmove(d,s,n*sizeof(TYPE));
     182             :     } else {
     183           0 :         d += n;
     184           0 :         s += n;
     185           0 :         while (n--) {
     186           0 :             --d, --s;
     187             :             if (!traits<TYPE>::has_trivial_copy) {
     188           0 :                 new(d) TYPE(*s);
     189             :             } else {
     190             :                 *d = *s;   
     191             :             }
     192             :             if (!traits<TYPE>::has_trivial_dtor) {
     193           0 :                 s->~TYPE();
     194             :             }
     195             :         }
     196             :     }
     197           0 : }
     198             : 
     199             : template<typename TYPE> inline
     200           0 : void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
     201             :     if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) 
     202             :             || traits<TYPE>::has_trivial_move) 
     203             :     {
     204           0 :         memmove((void*)d,(void*)s,n*sizeof(TYPE));
     205             :     } else {
     206           0 :         while (n--) {
     207             :             if (!traits<TYPE>::has_trivial_copy) {
     208           0 :                 new(d) TYPE(*s);
     209             :             } else {
     210             :                 *d = *s;   
     211             :             }
     212             :             if (!traits<TYPE>::has_trivial_dtor) {
     213           0 :                 s->~TYPE();
     214             :             }
     215           0 :             d++, s++;
     216             :         }
     217             :     }
     218           0 : }
     219             : 
     220             : // ---------------------------------------------------------------------------
     221             : 
     222             : /*
     223             :  * a key/value pair
     224             :  */
     225             : 
     226             : template <typename KEY, typename VALUE>
     227           0 : struct key_value_pair_t {
     228             :     typedef KEY key_t;
     229             :     typedef VALUE value_t;
     230             : 
     231             :     KEY     key;
     232             :     VALUE   value;
     233           0 :     key_value_pair_t() { }
     234           0 :     key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
     235           0 :     key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v)  { }
     236           0 :     key_value_pair_t(const KEY& k) : key(k) { }
     237           0 :     inline bool operator < (const key_value_pair_t& o) const {
     238           0 :         return strictly_order_type(key, o.key);
     239             :     }
     240             :     inline const KEY& getKey() const {
     241             :         return key;
     242             :     }
     243             :     inline const VALUE& getValue() const {
     244             :         return value;
     245             :     }
     246             : };
     247             : 
     248             : template <typename K, typename V>
     249             : struct trait_trivial_ctor< key_value_pair_t<K, V> >
     250             : { enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
     251             : template <typename K, typename V>
     252             : struct trait_trivial_dtor< key_value_pair_t<K, V> >
     253             : { enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
     254             : template <typename K, typename V>
     255             : struct trait_trivial_copy< key_value_pair_t<K, V> >
     256             : { enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
     257             : template <typename K, typename V>
     258             : struct trait_trivial_move< key_value_pair_t<K, V> >
     259             : { enum { value = aggregate_traits<K,V>::has_trivial_move }; };
     260             : 
     261             : // ---------------------------------------------------------------------------
     262             : 
     263             : /*
     264             :  * Hash codes.
     265             :  */
     266             : typedef uint32_t hash_t;
     267             : 
     268             : template <typename TKey>
     269             : hash_t hash_type(const TKey& key);
     270             : 
     271             : /* Built-in hash code specializations.
     272             :  * Assumes pointers are 32bit. */
     273             : #define ANDROID_INT32_HASH(T) \
     274             :         template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
     275             : #define ANDROID_INT64_HASH(T) \
     276             :         template <> inline hash_t hash_type(const T& value) { \
     277             :                 return hash_t((value >> 32) ^ value); }
     278             : #define ANDROID_REINTERPRET_HASH(T, R) \
     279             :         template <> inline hash_t hash_type(const T& value) { \
     280             :                 return hash_type(*reinterpret_cast<const R*>(&value)); }
     281             : 
     282             : ANDROID_INT32_HASH(bool)
     283             : ANDROID_INT32_HASH(int8_t)
     284             : ANDROID_INT32_HASH(uint8_t)
     285             : ANDROID_INT32_HASH(int16_t)
     286             : ANDROID_INT32_HASH(uint16_t)
     287             : ANDROID_INT32_HASH(int32_t)
     288             : ANDROID_INT32_HASH(uint32_t)
     289             : ANDROID_INT64_HASH(int64_t)
     290             : ANDROID_INT64_HASH(uint64_t)
     291             : ANDROID_REINTERPRET_HASH(float, uint32_t)
     292             : ANDROID_REINTERPRET_HASH(double, uint64_t)
     293             : 
     294             : template <typename T> inline hash_t hash_type(T* const & value) {
     295             :     return hash_type(uintptr_t(value));
     296             : }
     297             : 
     298             : }; // namespace stagefright
     299             : 
     300             : // ---------------------------------------------------------------------------
     301             : 
     302             : #endif // ANDROID_TYPE_HELPERS_H

Generated by: LCOV version 1.13