Merge pull request #2983 from koalefant/vector_ptr

Vector<>::_ptr is now typed and points to the beginning of the array rather than refcounting block
This commit is contained in:
Juan Linietsky 2015-12-08 17:02:13 -03:00
commit a6ac1fcd94

View file

@ -42,7 +42,7 @@
template<class T> template<class T>
class Vector { class Vector {
mutable void* _ptr; mutable T* _ptr;
// internal helpers // internal helpers
@ -51,21 +51,21 @@ class Vector {
if (!_ptr) if (!_ptr)
return NULL; return NULL;
return reinterpret_cast<SafeRefCount*>(_ptr); return reinterpret_cast<SafeRefCount*>((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount));
} }
_FORCE_INLINE_ int* _get_size() const { _FORCE_INLINE_ int* _get_size() const {
if (!_ptr) if (!_ptr)
return NULL; return NULL;
return reinterpret_cast<int*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount)); return reinterpret_cast<int*>((uint8_t*)_ptr-sizeof(int));
} }
_FORCE_INLINE_ T* _get_data() const { _FORCE_INLINE_ T* _get_data() const {
if (!_ptr) if (!_ptr)
return NULL; return NULL;
return reinterpret_cast<T*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount)+sizeof(int)); return reinterpret_cast<T*>(_ptr);
} }
@ -88,11 +88,11 @@ public:
_FORCE_INLINE_ void clear() { resize(0); } _FORCE_INLINE_ void clear() { resize(0); }
_FORCE_INLINE_ int size() const { _FORCE_INLINE_ int size() const {
int* size = _get_size();
if (!_ptr) if (size)
return 0; return *size;
else else
return *reinterpret_cast<int*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount)); return 0;
} }
_FORCE_INLINE_ bool empty() const { return _ptr == 0; } _FORCE_INLINE_ bool empty() const { return _ptr == 0; }
Error resize(int p_size); Error resize(int p_size);
@ -174,7 +174,7 @@ void Vector<T>::_unref(void *p_data) {
if (!p_data) if (!p_data)
return; return;
SafeRefCount *src = reinterpret_cast<SafeRefCount*>(p_data); SafeRefCount *src = reinterpret_cast<SafeRefCount*>((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount));
if (!src->unref()) if (!src->unref())
return; // still in use return; // still in use
@ -189,7 +189,7 @@ void Vector<T>::_unref(void *p_data) {
} }
// free mem // free mem
memfree(p_data); memfree((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount));
} }
@ -201,7 +201,8 @@ void Vector<T>::_copy_on_write() {
if (_get_refcount()->get() > 1 ) { if (_get_refcount()->get() > 1 ) {
/* in use by more than me */ /* in use by more than me */
SafeRefCount *src_new=(SafeRefCount *)memalloc(_get_alloc_size(*_get_size())); void* mem_new = memalloc(_get_alloc_size(*_get_size()));
SafeRefCount *src_new=(SafeRefCount *)mem_new;
src_new->init(); src_new->init();
int * _size = (int*)(src_new+1); int * _size = (int*)(src_new+1);
*_size=*_get_size(); *_size=*_get_size();
@ -215,7 +216,7 @@ void Vector<T>::_copy_on_write() {
} }
_unref(_ptr); _unref(_ptr);
_ptr=src_new; _ptr=_data;
} }
} }
@ -260,16 +261,17 @@ Error Vector<T>::resize(int p_size) {
if (size()==0) { if (size()==0) {
// alloc from scratch // alloc from scratch
_ptr = (T*)memalloc(_get_alloc_size(p_size)); void* ptr=memalloc(_get_alloc_size(p_size));
ERR_FAIL_COND_V( !_ptr ,ERR_OUT_OF_MEMORY); ERR_FAIL_COND_V( !ptr ,ERR_OUT_OF_MEMORY);
_ptr=(T*)((uint8_t*)ptr+sizeof(int)+sizeof(SafeRefCount));
_get_refcount()->init(); // init refcount _get_refcount()->init(); // init refcount
*_get_size()=0; // init size (currently, none) *_get_size()=0; // init size (currently, none)
} else { } else {
void *_ptrnew = (T*)memrealloc(_ptr,_get_alloc_size(p_size)); void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY); ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
_ptr=_ptrnew; _ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
} }
// construct the newly created elements // construct the newly created elements
@ -291,10 +293,10 @@ Error Vector<T>::resize(int p_size) {
t->~T(); t->~T();
} }
void *_ptrnew = (T*)memrealloc(_ptr,_get_alloc_size(p_size)); void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY); ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
_ptr=_ptrnew; _ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
*_get_size()=p_size; *_get_size()=p_size;