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
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
00021 is_pointer = trait_pointer<TYPE>::value,
00022
00023 has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value,
00024
00025 has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value,
00026
00027 has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value,
00028
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 {
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 }
00194
00195 #endif //end of lib