libutils_stl.h
Go to the documentation of this file.
00001 #if !defined(HFILE_libutils_stl) && ANDROID_VER>=400
00002 #define HFILE_libutils_stl
00003 
00004 #include "libutils.h"
00005 #include <new>
00006 
00007 namespace android {
00008 
00010 //from TypeHelpers.h
00011 template <typename T> struct trait_trivial_ctor { enum { value = false }; };
00012 template <typename T> struct trait_trivial_dtor { enum { value = false }; };
00013 template <typename T> struct trait_trivial_copy { enum { value = false }; };
00014 template <typename T> struct trait_trivial_move { enum { value = false }; };
00015 template <typename T> struct trait_pointer      { enum { value = false }; };
00016 template <typename T> struct trait_pointer<T*>  { enum { value = true }; };
00017 
00018 template <typename TYPE> struct traits {
00019     enum {
00020         // whether this type is a pointer
00021         is_pointer          = trait_pointer<TYPE>::value,
00022         // whether this type's constructor is a no-op
00023         has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
00024         // whether this type's destructor is a no-op
00025         has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
00026         // whether this type type can be copy-constructed with memcpy
00027         has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
00028         // whether this type can be moved with memmove
00029         has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
00030     };
00031 };
00032 
00033 #define ANDROID_TRIVIAL_CTOR_TRAIT( T ) template<> struct trait_trivial_ctor< T >   { enum { value = true }; };
00034 #define ANDROID_TRIVIAL_DTOR_TRAIT( T ) template<> struct trait_trivial_dtor< T >   { enum { value = true }; };
00035 #define ANDROID_TRIVIAL_COPY_TRAIT( T ) template<> struct trait_trivial_copy< T >   { enum { value = true }; };
00036 #define ANDROID_TRIVIAL_MOVE_TRAIT( T ) template<> struct trait_trivial_move< T >   { enum { value = true }; };
00037 
00038 #define ANDROID_BASIC_TYPES_TRAITS( T ) ANDROID_TRIVIAL_CTOR_TRAIT( T ) ANDROID_TRIVIAL_DTOR_TRAIT( T ) ANDROID_TRIVIAL_COPY_TRAIT( T ) ANDROID_TRIVIAL_MOVE_TRAIT( T )
00039 
00040 ANDROID_BASIC_TYPES_TRAITS( void )
00041 ANDROID_BASIC_TYPES_TRAITS( bool )
00042 ANDROID_BASIC_TYPES_TRAITS( char )
00043 ANDROID_BASIC_TYPES_TRAITS( unsigned char )
00044 ANDROID_BASIC_TYPES_TRAITS( short )
00045 ANDROID_BASIC_TYPES_TRAITS( unsigned short )
00046 ANDROID_BASIC_TYPES_TRAITS( int )
00047 ANDROID_BASIC_TYPES_TRAITS( unsigned int )
00048 ANDROID_BASIC_TYPES_TRAITS( long )
00049 ANDROID_BASIC_TYPES_TRAITS( unsigned long )
00050 ANDROID_BASIC_TYPES_TRAITS( long long )
00051 ANDROID_BASIC_TYPES_TRAITS( unsigned long long )
00052 ANDROID_BASIC_TYPES_TRAITS( float )
00053 ANDROID_BASIC_TYPES_TRAITS( double )
00054 
00055 template<typename TYPE> inline
00056 void construct_type(TYPE* p, size_t n) {
00057     if (!traits<TYPE>::has_trivial_ctor) {
00058         while (n--) {
00059             new(p++) TYPE;
00060         }
00061     }
00062 }
00063 
00064 template<typename TYPE> inline
00065 void destroy_type(TYPE* p, size_t n) {
00066     if (!traits<TYPE>::has_trivial_dtor) {
00067         while (n--) {
00068             p->~TYPE();
00069             p++;
00070         }
00071     }
00072 }
00073 
00074 template<typename TYPE> inline
00075 void copy_type(TYPE* d, const TYPE* s, size_t n) {
00076     if (!traits<TYPE>::has_trivial_copy) {
00077         while (n--) {
00078             new(d) TYPE(*s);
00079             d++, s++;
00080         }
00081     } else {
00082         memcpy(d,s,n*sizeof(TYPE));
00083     }
00084 }
00085 
00086 template<typename TYPE> inline
00087 void splat_type(TYPE* where, const TYPE* what, size_t n) {
00088     if (!traits<TYPE>::has_trivial_copy) {
00089         while (n--) {
00090             new(where) TYPE(*what);
00091             where++;
00092         }
00093     } else {
00094         while (n--) {
00095             *where++ = *what;
00096         }
00097     }
00098 }
00099 
00100 template<typename TYPE> inline
00101 void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
00102     if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
00103             || traits<TYPE>::has_trivial_move)
00104     {
00105         memmove(d,s,n*sizeof(TYPE));
00106     } else {
00107         d += n;
00108         s += n;
00109         while (n--) {
00110             --d, --s;
00111             if (!traits<TYPE>::has_trivial_copy) {
00112                 new(d) TYPE(*s);
00113             } else {
00114                 *d = *s;
00115             }
00116             if (!traits<TYPE>::has_trivial_dtor) {
00117                 s->~TYPE();
00118             }
00119         }
00120     }
00121 }
00122 
00123 template<typename TYPE> inline
00124 void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
00125     if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy)
00126             || traits<TYPE>::has_trivial_move)
00127     {
00128         memmove(d,s,n*sizeof(TYPE));
00129     } else {
00130         while (n--) {
00131             if (!traits<TYPE>::has_trivial_copy) {
00132                 new(d) TYPE(*s);
00133             } else {
00134                 *d = *s;
00135             }
00136             if (!traits<TYPE>::has_trivial_dtor) {
00137                 s->~TYPE();
00138             }
00139             d++, s++;
00140         }
00141     }
00142 }
00144 
00145 class VectorImpl {
00146 public:
00147     enum { // flags passed to the ctor
00148         HAS_TRIVIAL_CTOR    = 0x00000001,
00149         HAS_TRIVIAL_DTOR    = 0x00000002,
00150         HAS_TRIVIAL_COPY    = 0x00000004,
00151     };
00152     VectorImpl(size_t itemSize, uint32_t flags);
00153     virtual ~VectorImpl();
00154     ssize_t         add();
00155     void*           editArrayImpl();
00156     void*           editItemLocation(size_t index);
00157     void            finish_vector();
00158     inline  size_t  size() const { return mCount; }
00159 protected:
00160     virtual void do_construct(void* storage, size_t num) const = 0;
00161     virtual void do_destroy(void* storage, size_t num) const = 0;
00162     virtual void do_copy(void* dest, const void* from, size_t num) const = 0;
00163     virtual void do_splat(void* dest, const void* item, size_t num) const = 0;
00164     virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0;
00165     virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0;
00166 private:
00167     void *   mStorage;
00168     size_t   mCount;
00169     uint32_t mFlags;
00170     size_t   mItemSize;
00171 };
00172 
00173 template <class TYPE> class Vector : private VectorImpl {
00174 public:
00175     Vector() : VectorImpl(sizeof(TYPE), ((traits<TYPE>::has_trivial_ctor? HAS_TRIVIAL_CTOR: 0)|(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0)|(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0))) {}
00176     virtual ~Vector() {finish_vector();}
00177     inline  ssize_t         add() {return VectorImpl::add();}
00178     inline  TYPE*           editArray() {return static_cast<TYPE *>(editArrayImpl());}
00179     inline  TYPE&           editItemAt(size_t index) {return *( static_cast<TYPE *>(editItemLocation(index)) );}
00180     inline  size_t          size() const {return VectorImpl::size();}
00181 protected:
00182     virtual void do_construct(void* storage, size_t num) const { construct_type( reinterpret_cast<TYPE*>(storage), num ); }
00183     virtual void do_destroy(void* storage, size_t num) const { destroy_type( reinterpret_cast<TYPE*>(storage), num ); }
00184     virtual void do_copy(void* dest, const void* from, size_t num) const { copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); }
00185     virtual void do_splat(void* dest, const void* item, size_t num) const { splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num ); }
00186     virtual void do_move_forward(void* dest, const void* from, size_t num) const { move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); }
00187     virtual void do_move_backward(void* dest, const void* from, size_t num) const { move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); }
00188 };
00189 
00190 ANDROID_TRIVIAL_MOVE_TRAIT(String16)
00191 ANDROID_TRIVIAL_MOVE_TRAIT(String8)
00192 
00193 } //end of namespace android
00194 
00195 #endif //end of lib


dji_ronin
Author(s):
autogenerated on Sat Jun 8 2019 20:15:31